Avoiding blowups

What is a "blowup"?

A blowup is when the sound produced by your SC server cuts out entirely, due to the generation of a "NaN" ("not a number") value somewhere in the sound-generating graphs.

These can be very bad for your live performance, since the only way to restore the sound is to reboot the SC server.

Sometimes these will be caused directly by the coding within your synth graphs, and sometimes by certain UGens being prone to blow up when fed certain patterns of input.

What is NaN?

There are mathematical operations to which the answer is undefined, and many computer languages include the concept of NaN to be used in such situations. For example, dividing by zero in SC will return the value "inf", representing infinity. But what happens if you divide infinity by infinity? The answer is not defined, so according to SC,

inf / inf = nan

This means that it's perfectly possible to write Synths which result in NaN output, unintentionally. Often it is caused by accidental divide-by-zero, which will create an infinite value which may then (although not necessarily) result in NaN.

How does it kill the whole server's sound?

No mathematical operations at all can be performed on NaN. So if you have 5 nodes all playing completely independently on the same server, and one of them emits a NaN value, then the overall output is NaN plus four other values. NaN plus anything results in NaN, so the overall output from the server will be a constant NaN.

When do blowups happen in SC?

NaN can result directly from calculations performed within your SC code, or within UGens you might be using, if the UGens receive "unexpected" input. Here's an example - note how the second "bad" synth also affects the first "good" synth:

```s.boot; // Start the server afresh

x = {Saw.ar(213.7, 0.1)}.play; // A simple synth, whose output we'll destroy later

y = {Saw.ar((313.7/0.0)/(1.0/MouseX.kr(0,100)), 0.1)}.play; // Move the mouse, and cause NaN

y.free; // Since this completely stops the second synth, you might expect to be able to hear x once more - but no

```

Shouldn't UGens "insulate" an SC programmer from blowups? Is a UGen badly written if it can blow up?

The way to prevent blowups is by adding checks, e.g. for divide-by-zero. This adds a (small) computational burden into the functions, and so some would say that it is better not to over-burden the processor, but to expect the SC programmer to know about the potential for blowups and to code around them, e.g. by checking values before they are passed in as arguments. For UGens with an explicitly limited applicability (such as FSinOsc, designed for speed but only usable with relatively stable frequency input) this is certainly true.

When working with generative systems which automatically create networks of UGens, this can become increasingly unmanageable and quite annoying, since many blowup risks are not indicated at all in the relevant helpfiles.

How can I avoid blowups?

Read the list of known blowups (further down this page), and try and avoid them by checking arguments and variables for sanity where neccessary.

Use clips, soft saturation, limiters, etc. to keep the signal within known bounds. For example, infinities can be tamed quite easily: inf.clip2(1,-1) = 1

Known blowups

• Attempting a mathematical operation with an undefined result, such as (inf - inf), or (inf / inf) - most commonly this results from divide-by-zero.

• The standard filter UGens, LPF, HPF, RLPF, RHPF, can blow up in certain conditions, with unusual values to the cutoff frequency argument.

• FSinOsc is a very processor-efficient sine oscillator, but is prone to blowups because of the generation method (using a ringing oscillator). In most cases, stick with SinOsc to avoid blowups if the frequency input is likely to change fast. This limitation is well-documented in FSinOsc's helpfile.

• Spring.ar seems to blow up in a variety of situations, although I haven't been able to pin down exactly which conditions cause this.

• I'm not sure why this blows up - perhaps because of the audio-rate and fast-changing frequency input to the saw oscillator? { LFSaw.ar(10 ** (PinkNoise.ar+1)50,0,1, 0)}.play;