Originally authored by Celeste Hutchins
This document is heavily influenced by the very talented SuperCollider programmer Celeste Hutchins. Ok it is an almost direct ripe off of his (at least I think it his) written tutorial written back in 2005 for the Mac. Whilst preparing this document however it has occurred to me just how complex this particular introduction is and as a result decided to reorganise it's document position. As an introduction to Classes and Objects I consider this a concise document. For this reason I have decided to maximise it's document position until I can more correctly place this document logically.
Start Applications >> Audio & Video >> JACK Control
If top left Start button is Green select it
This needs to start with no errors
Start Applications >> Accessories >> Text Editor (Gedit)
Start Tools >> SuperCollider mode
Start from SuperCollider menu >> Start Server
Monitor the lower Frame of the Text Editor (Gedit) display for errors
SinOsc = Sine Oscillator
RLPF = Reasonant Low Pass Filter
Saw = Saw Tooth Oscillator
LFNoise1 = Low Frequency Noise
play = Play sound to Audio O/P
.ar = Audio Rate (eg. SinOsc.ar)
.kr = Control Rate(eg. SinOsc.kr)
mul = Not a clue
add = Err adding something
Basic's 02 is still an introductory level tutorial for SuperCollider in this tutorial we aim to look at and produce simple sounds of a single tone using the SinOsc (Sine Oscillator) command.
Place this code into your Text Editor and use a blank template
)
The goal of this document is to teach you SuperCollider, and some basic programming concepts and terminology. These concepts are the same across many programming languages.
What is a program? It's a series of instructions that a computer follows to complete a task. A program is a lot like a musical score. You play a score in order from left to right, playing each note or rest one after the other, jumping backwards in case of repeats and forwards in cases of things like second endings or codas. In the same way, you can tell your computer to play a B for two seconds and then an A and tell it to repeat back and so on. You're able to tell your computer to do more complicated things to, like play a C if you move your mouse to the upper right hand corner and a D in the left hand, or make more complicated sounds. In order to tell all these things to your computer, you need to be able to speak the same language as it does. SuperCollider is a programming language designed for writing musical programs.
When you click on the SuperCollider in the tools menu, two windows will appear within the Text Editor (Gedit) you are using. The text window called "Untitled" will allow you to create and paste examples into it, the smaller window below is more like a Server Monitor. If there is an error in your Interpreted program in the Untitled window no direct feedback is obvious, however as you try to run the created program the server Monitor windows will display all errors use this as your debug window. However you will still need to initiate or start the SuperCollider Server this is accomplished in the SuperCollider menu within the Text Editor (Gedit) application.
To write your own code, you must open a new window, which you can do under the File menu. To execute any code you have written you must move you cursor to the BLANK line containing your first opening bracket. To stop code that is running, use the ESC key located at the top left hand side of your keyboard.
In Supercollider, blocks of code are enclosed in parentheses. To run an entire block, click your mouse on the first line of the open parenthesis and select Control KEY plus E.
SuperCollider is an object-oriented language. The text "hello world" is a type of object called a String. A string is any piece of text surrounded by double quotes. There are other objects, for example, integers, or floating point numbers, or Arrays, which we'll talk about later. We can communicate with objects by using methods defined by the author of the object. In the above example, we're sending a message of postln to the string. That message tells the string to print itself.
We can think of the example of a light switch. If you want to turn on a light, you flip on the switch. This is like sending a message to the light bulb saying, "Hey, turn on." If we flip the switch down, it's like sending a message of "hey, turn off."
Let's think of a person, Nicole, as an object. Now, Nicole, herself is an object, but the word "Nicole" is a name that refers to Nicole the person. Similarly, we can give names to our objects. These names are called variables.
var greeting;
greeting = "hello world";
greeting.postln;
)
What's going on there? The first word, "var," is short for variable. A variable is a storage location, it's a place to store a piece of data in this case a string. The contents of data stored may vary, which is why it's called "var" a variable, and is considered a reserve word.
The second word "greeting" is a label for the string of type var. If var was an address envelope then the contents of the envelope would be the string "hello world"; Here we are declaring to "var" that greeting is the variable name. Bringing us back to the envelope a moment the address of the envelope in this instance would be greeting.
In the interpreted program we will have a variable named "greeting." The interpreter is the part of SuperCollider that reads and runs our programs. So, when the interpreter reads our program and sees the word "greeting" it will know that greeting is a variable that we've created it. Otherwise, it wouldn't know what we were talking about or what to do with it. All variable names in SuperCollider must start with a lowercase letter and cannot be a reserved word. So you cannot have a variable called "var" because var already has a special meaning to the interpreter it is a reserved word.
Next we assign a value to the variable, greeting gets the string "hello world". The variable name is on the left of the equal sign. It must always be on the left. There can only ever be one thing on the left of an equals sign. That sign is saying, hey, take whatever is on the right of this equals sign and store it under the variable name on the left.
In the last line, we're sending a postln message to the variable. The SuperCollider interpreter sends that message to greeting, greeting is a String. Strings are printed when the variable is called with the postln message. So because the contents of greeting is a String, and these contents of greeting, "hello world", are print out. On the left is the variable name, an object. Then there is a period. Then greeting is the name of the message. There are a few different coding styles allowable in SuperCollider, but we're going to focus on receiver notation because it is common across many programming languages. That is:
object.message;
var greeting
greeting="hello world" therefore the object called greeting holds in it's contents "hello world"
Notice that every line ends with a semi-colon. In Supercollider, all lines must terminate with a semi-colon. Later on, when you're trying to figure out why some program isn't working, you're going to discover a missing semicolon. The semicolon tells the interpreter that you're done with that instruction. A single instruction can span as many lines as you need it to, but it must end with a semicolon.
Let's make some sound. First, make sure SuperCollider plugin is enabled in Text Editor (Gedit). Then start SuperCollider Sound Server also ensure Jack control is running errors will be displayed in Text Editor (Gedit) Server Monitor if Jack not running.
var syn, sound;
syn = SynthDef.new("example1", {
Out.ar(0, SinOsc.ar(440));
});
syn.load(s);
sound = Synth.new("example1");
// Press ESC to end
)
What's going on here? Programs in SuperCollider are interpreted. That means that you have to run them from within the SuperCollider interpreter. As a result you only get messages forwarded to the Server monitor just below your edit screen in your Tex Editor (Gedit), telling you SuperCollider is running or has failed to run it as a program.
Our program first declares a variable, and then it defines a SynthDef "Synthesizer Definition" and loads it on the server, then creates a Synth object that plays the sound. This is a complicated stuff as an example, but I wanted to get you making sounds as soon as possible. Let's look at the example line by line.
The first line of our program is an open paren. Blocks of code are surrounded by parentheses in SuperCollider.
The next line is var syn, sound;. We are declaring two variables. One is called syn and the other is called sound.
The next line, translated into English, means "I want to create a new Synthesizer Definition "SynthDef" called 'example1' and store it in the variable syn." Whoa, what's a SynthDef? The SynthDef help file told me that a SynthDef is a "definition of a synth architecture."
SuperCollider is not just one program; it is two. One part of the program is the interpreter, which is what we've been talking about so far. The other part of the program is audio server, which is what actually makes the sound. The audio server runs separately from the interpreter, but they can communicate with each other using something called OSC, which we will talk about later.
The server does not know anything but what it needs to know. This makes it run much faster and more efficiently. You can tell it to make certain kinds of sounds, but in order to run quickly, it wants to know what kinds of sounds you want before you actually making them. So in effect you write a description of what you want the server to do. This description, or definition, in this case is called a SynthDef.
SynthDef is the name of a class. Object definitions are called classes. An object is a particular instance of a class. In SuperCollider, all class names start with a capital letter.
Examples: Nicole is an example of a person. Remember that Nicole is an object. "Person" would be his class. Likewise, SynthDef is a class.
There are certain types of messages that you can send to a class. One of those is called a constructor. The message ".new" is a constructor. It tells the class to make a new instance of itself. So when we call SynthDef.new, we get back a new SynthDef, which we’re storing, in the variable name syn.
Inside the parenthesis are some arguments. Some messages, like postln, know what to do when they're called - if we put postln after a String like we did above with "hello world".postln, the message just knows to print whatever the string is. Other messages require more information, which we call arguments. Notice that we have an object, a message and arguments. The way we code those is:
object.message(argument1, argument2, ... argumentN);Or
Class.message(argument1, argument2, ... argumentN);In the case of our SynthDef, SynthDef is the class. new is the message. And "example1" and the stuff in between the curly brackets are the two arguments. The stuff in the curly brackets is telling the SynthDef what to play. Things between curly brackets {} are called functions. A function is a special type of object that is made up of a code block that you can run. We'll come back to this later as well.
Out is a UGen. The help file for UGens says, "A UGen or unit generator is an object for generating or processing audio or control signals." UGens exist in SynthDefs. They are what make up a SynthDef. Out is a UGen that writes a signal to a bus, which, in this case, sends it's output to the left channel. .ar is a type of constructor. So Out.ar creates a new instance of a an Out UGen running at the audio rate. ar stands for "audio rate" and is a common constructor name for UGens.
Looking at the arguments to Out.ar, 0 means left channel. If that were a 1, it would mean right channel. And the next thing is what gets sent out, which is a sine tone generator. The argument to SinOsc.ar, 440, is the frequency to play.
So SinOsc.ar(440) creates a sine wave at 440 Hz. Out.ar takes that sine wave and sends it out to the left channel, which is channel 0.
The next line, is a closing curly bracket, a close paren and a semicolon. It's the end of the function and the end of the SynthDef, or the end of a statement. We've created a new SynthDef that includes in it a function describing what the SynthDef should do when it gets instantiated.
The next line says, take that SynthDef and load it on the server. We're sending a message to syn, saying load. The argument, s, is the server to send it to. In SuperCollider, a lowercase s by itself refers to the audio server.
The next line asks to create a new Synth. A Synth is an instance of a SynthDef. The interpreter sends a message to the server, saying, "Hey, could you make a synth that plays the SynthDef called 'example1'?" The server looks and says, "oh yeah, I have a SynthDef called that" and makes a new instance of a Synth, which is running the function that we defined.
We get a new Synth object back from this and store it in "sound." Let's say we don't want to play an A. Let's say we want to play an E. We can change 440 to 660.
var sdef;
sdef = SynthDef.new("example1", {
Out.ar(0, SinOsc.ar(660));
});
sdef.play;
// Press ESC to end
)
But when we're writing a piece, we don't want to have to write a new SynthDef for every note that we're going to play. We can create out own argument, which will tell the SynthDef what frequency to play.
var syn, sound;
syn = SynthDef.new("example1", { arg freq;
Out.ar(0, SinOsc.ar(freq));
});
syn.load(s);
sound = Synth.new("example1", [\freq, 440]);
// Press ESC to end
)
We call that argument “freq.” An argument is a special kind of variable. You declare them at the top of a code block by using the reserved word “arg.” So the “arg freq;” part of “syn = SynthDef.new("example1", { arg freq;” tells SuperCollider that our SynthDef function takes a single argument called freq. We can then use freq like we would any other variable. Here, we’re passing to SinOsc.ar, to use for the frequency passed to it.
Passing variables to Synths is a bit different than normal variable passing. The interpreter has to communicate with the audio server. They use a protocol called OSC. The Synth object will handle the OSC for you, but the server does not know which argument you’re trying to pass a value to unless you specifically tell it. So Synth.new takes an optional second argument, which is an Array. An array is a list separated by commas and surrounded by square brackets. When you are passing arguments to the server via a synth, the array must be made up of pairs. The first item in a pair is a symbol or a string and the second is a value. The symbol or string must match the name of the argument. So for an argument called freq, we use the symbol \freq or the string “freq”. If we had an argument called foo, we would use the symbol \foo or the string “foo”. A symbol always starts with a backward slash: ‘\’. So to pass a value of 440 to the argument freq, our array contains [\freq, 440]. If we had two arguments, one freq and the other foo, we could pass values to freq and foo with an array that looks like [\freq, 440, \foo 647]. The array is made up of pairs, to the 440 goes to freq and 647 goes to foo. The symbols or strings must match the names of the arguments taken by the SynthDef function.
We hope this tutorial will help you get started with SuperCollider. Make sure you also stop by the SuperCollider website and the wiki for more tutorials and examples. Hopefully we have wetted your appetite for SuperCollider this small Tutorial is just the start for further information it is suggested you visit the following site</code> SuperCollider Help Files To obtain a list of UGens type this reserve word into your editor highlight and press Control + "u".