After reading a great paper by Julian Rohrhuber which really opened my eyes to the <>> and <<> operators. They make Ndefs very easy to patch together, and making SC easier which is a great thing.

So heres a rephrased version of what's presented in that paper, which I hope eases into the concepts a little more slowly, as well as some pitfalls I found when starting to use it. But first an introduction to Ndefs and making sound in SuperCollider in general...

Introduction

This page is mainly about Ndefs and how to use them for sound design in SuperCollider. I'll start off with the basics of Ndefs and then move into routing techniques as outlined in Julian Rohrhuber paper (above).

Getting started

The "hello world" (most basic program) in SuperCollider (SC) might look like this:

{ SinOsc.ar }.play

Copy/paste that into a new SC window (Apple + n), make sure your cursor is on the same line, and press enter. You should hear a Sine tone at 440Hz or the note A above middle C (if you prefer). But the first thing you'll notice is that you want to stop it. Which is clumsily done by pressing:

Apple + .

This is the "All sound off" command and is clumsy because if you have any other sounds running they will also be killed, and in the middle of a recording/performance this is a high price for a mistake.

So we can control it like so

a = { SinOsc.ar(220) }.play;
a.free

The function that makes the sound also returns a 'handle' or 'pointer' to the thing, a Node, that is making the sound (on the sound server). Here we keep track of the Node we just created by assigning this handle to a variable a. You don't need to do this (see first example) but once we have this handle to our sound Node we can control it, and the sound, a little more elegantly. Which is what we do on the second line and stop the sound, free the Node, with code instead of a keyboard command.

Here you'll note I also changed the pitch of the sound to 220Hz which is the note A bellow middle C (ie. one octave down). Try changing the pitch value from 220 to any number between 40 and 10000. Try doing this without running the second line in between. You'll find you have to use the clumsy "All sound off" keyboard command to make them all stop.

Faster composition with Ndef

So you can create sound and stop it, which is the cycle you have to go though if you start designing sounds. Starting and stopping between each change you make is a bit tedious when what you want to do is replace the old sound with the new one. We can cut one step out if we use Ndefs:

Ndef(\x, { SinOsc.ar(110) }).play

Now if you play this you'll get a Sine tone (A, 2 octaves bellow middle C), as before, but if you change the code between the curly brackets {}. Notice also that we have also given it a name, \x, which we can use to control it later.

Try to just change the 110 to a number between 40 and 10000) you'll notice that the old sound is replaced with the new one. Try this one:

Ndef(\x, { SinOsc.ar(SinOsc.ar(100) * 111 + 222) } ).play

Here we're doing a little Frequency Modulation (FM) and getting a more interesting sound. You can see instead of a simple number for frequency like 110 as before I've replaced it with another Sine oscillator which is "modulating" the frequency of the outer Sine oscillator at 100Hz. Since the SinOsc generates a signal with a value between -1 and 1, and we want it to output frequency values for the outer oscillator, I've multiplied it by 111, so then its between -111 and 111. Then added 222 to move it up to between 111 and 333 (if you remember your trigonometry from high school).

To stop it use:

Ndef(\x).stop

To play again is simply:

Ndef(\x).play

You'll note to control the Ndef all we have to do is to use the \x reference in the round brackets ( ) and then attach a command with a dot e.g. .stop.

You can see that this trick of changing the sounds definition and then replacing the old version that is playing is a very quick way to experiment with designing your sounds. See Sound Synthesis Techniques for some ideas to get you started in this direction and then come back here.

Routing sound with Ndefs

Now we focus more on Ndefs and how we can use them to route sound around in different ways.

Feedback

Ndefs are very flexible and make routing sound around very simple. A basic example is creating feedback by put an Ndef inside itself like so:

(
    Ndef(\z, {
        SinOsc.ar(
            LFNoise0.kr(12 ! 2, 100, 160)
            , Ndef(\z).ar * 0.9
        )
    }).play
)

Here the \z Ndef's SinOsc is having its frequency modulated (FM) by the LFNoise. The second argument of the SinOsc is its phase which is being modulated by the output of Ndef(\z).

Patching in realtime

OK, so the main advantage of the Ndef way of working is that you can easily route the outputs from one to the input of another in realtime (i.e. "live" which is why they sometimes call this Live Coding) like a modular synth. Here we start to use the <<> symbol to route the audio signal.

We might rewrite the above like so:

(
    Ndef(\z, {
        SinOsc.ar(
            LFNoise0.kr(12 ! 2, 100, 160)
            , \in.ar(0 ! 2) * 0.9
        )
    }).play

    Ndef(\z) <<> Ndef(\z)
)

Here we have introduced the use of a symbol (i.e. a word beginning with a \), in this case \in.ar as a short cut for writing a parameter to the Ndef. Later we'll see others if you want to facilitate multiple inputs.

The last line

Beginners Pitfalls

Well, at least the ones I had.

Play the last Ndef in the chain

I started out trying to play the sound generating UGen at the beginning of the chain and as a result its output didn't pass though all the filters I'd setup. I guess because by playing it your sending the.

??? Example.

"WARNING: Could not link node proxies, no matching input found."

I got this a lot and figured out that the data rate (i.e. ether audio rate ".ar" or kontrol rate ".kr") need to match for the output of one Ndef to the input you are trying to stick into into it.)

??? Example.

Also, the number of channels must also match.

??? Example.

Also see

Approach to Working with SuperCollider in Improvisations
A short discussion about a similar approch to working in SuperCollider