Product SiteDocumentation Site

11.3.10.2. SynthDef

A SynthDef is what we use to tell the server how to create sound. In order to truly understand what SynthDef accomplishes, we need to recall the disconnect between the interpreter and the server. In reality, the interpreter has no idea how to make sound or work with audio hardware. The server, likewise, has no understanding at all of the SuperCollider language. The interpreter takes the code that we write, and does one of a number of things, depending on the nature of the code:
  • executes it completely,
  • executes it partially, makes choices, and then does something else
  • send the server information about how to synthesize sound,
  • etc.
For simple code like 2.postln; the interpreter just executes it. For code like { SincOsc.ar; }.play; the interpreter expands it a bit, then sends instructions to the server, which deals with the rest of the synthesis process.
A SynthDef is part of this last process; SynthDef Objects represent the synthesis information that is sent to the server before (or at the same time as) telling the server to play the sound.
There are two steps to creating a useful SynthDef: making an interpreter Object, and sending the actual synthesis information to the server. There are two ways to write this, as follows:
someVariable = SynthDef.new( nameOfSynthDef, FunctionContainingOutUGen );
someVariable.send( nameOfServer );
and
SynthDef.new( nameOfSynthDef, FunctionContainingOutUGen ).send( nameOfServer );
The FunctionContainingOutUGen is simply that - a function that, when executed, returns an Out UGen (meaning that the Out UGen must be the last expression in the function). The nameOfSynthDef should be a symbol (as described in Section 11.3.10.4, “Symbols”), but can also be a string. The nameOfServer is a variable that represents the server to which you want to send the SynthDef's information; unless you know that you need to use a different variable for this, it's probably just the letter "s", which the interpreter automatically assigns to the default server.
Here is a demonstration of both methods:
(
   var playMe =
   {
      Out.ar( 0, SinOsc.ar( freq:440, mul:0.2 ) );
   };

   var playMeSynthDef = SynthDef.new( \playMe, playMe );

   playMeSynthDef.send( s );

   nil;
)
and
(
   var playMe =
   {
      Out.ar( 0, SinOsc.ar( freq:440, mul:0.2 ) );
   };

   SynthDef.new( \playMe, playMe ).send( s );

   nil;
)
The only advantage to assigning something to a variable is the ability to refer to it later. If you use the first method, then you can send the SynthDef to more than one server. Since it's rare that you will want to use more than one server, it's usually better to use the second style. In fact, if you won't be using the "playMe" Function again, you don't need to assign it to a variable!
SynthDef.new( \playMe, { Out.ar( 0, SinOsc.ar( freq:440, mul:0.2 ) ); } ).send( s );
This is all that's really needed to create and send a synthesis definition to the server. It looks long and frightening, but now at least you understand what all of the parts do.