View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide

Cottle Chapter 2 - The Language, Programming Basics

Home   How To   Code Pool   Public Library   Theory   Events
[Cottle examples]

Example 1 - first patch

// Since scope will be used later, we should use the internal server now.
// Convention is to use the interpreter variable s for the server being used.
s = Server.internal;

// The server must be started before synthesis can begin.
s.boot;

// Ex. 1 actually plays with almost no modification, except that you have to tell
// it to use the internal server with the (s) at the end.
{ SinOsc.ar(LFNoise0.ar(10, 400, 800), 0, 0.3) }.play(s);

// stop it by pressing cmd-.
// Linux: In emacs, C-c C-s or Stop Main from the SCLang menu.
// Linux notes by DLP are emacs-specific

// Same thing, but assign the Synth object returned to a variable.
a = { SinOsc.ar(LFNoise0.ar(10, 400, 800), 0, 0.3) }.play(s);

// Stop it by talking to the variable.
a.free;

// What's going on in there?
// The function { SinOsc... } is being wrapped in a SynthDef.
// A SynthDef is a fixed arrangement of unit generators that can be reused at will.
// The above (considered a shortcut syntax in sc3, generally used only for testing)
// creates a SynthDef behind the scenes, sends it to the server, and plays it.
// If you write your own SynthDefs explicitly, you have more control over how they're
// built and used.

// Let's break those steps up:

// Write the patch into a synthdef and send it to the server.
// Lines enclosed in () should be executed all at once.
// Select the whole block by double-clicking to the right of the open-paren.
// Or, position the cursor inside the outer-level parens and press cmd-shift-B.

// Linux: Double-click on first parenthesis to select block. C-c C-c evaluates.

(
SynthDef.new("ch2-ex1", {
	Out.ar(0,	// an Out ugen is needed to send the signal to a bus
				// bus 0 is the hardware out, left channel
		SinOsc.ar(	// a sine wave oscillator
			LFNoise0.ar(10, 400, 800),	// randomly choose a frequency every 0.1 sec
			0,	// phase: constant 0
			0.3	// amplitude: constant 0.3
		)
	)
}).send(s);
)

// Play it and assign the resulting synth object to a variable.
a = Synth.new("ch2-ex1", target: s);

// Stop it by talking to the variable.
a.free;

// Do the same thing by talking directly to the server.
// s_new makes the new synth on the server. The synthdef name must be specified.
// The synth receives an id of 1000, is played at the head of the target group,
// and is placed into group 0.
s.sendMsg(\s_new, "ch2-ex1", 1000, 0, 0);

// Stop it by freeing synth ID 1000.
s.sendMsg(\n_free, 1000);

// When you say a = Synth.new("ch2-ex1", target: s), the language constructs the
// OSC message [\s_new, "ch2-ex1", 1000, 0, 0] and sends it to the server.
// The synth ID may be different.

// The synth object assigned to a is a language-side placeholder representing the
// synth on the server. Saying a.free builds the message [\n_free, 1000] and
// sends to the server.

// When you use Synth, Group, Bus, Buffer objects etc., they build OSC messages
// internally to communicate with the server. This is important to understand how
// these objects work. Unlike sc2, an sc3 Synth object does no sound processing on
// its own. It is merely a proxy to talk to server-side synths more conveniently
// from the language.

// Another shortcut syntax for testing:
(
a = SynthDef.new("ch2-ex1", {
	Out.ar(0, SinOsc.ar(LFNoise0.ar(10, 400, 800), 0, 0.3))
}).play(s);
)

a.free;


// Example 2 - second patch
// Note that the server is already booted from the last example, so we don't
// have to do it again.

(
SynthDef.new("ch2-ex2", {
	Out.ar(0, 
		RLPF.ar(	// Resonant Low-Pass Filter
			LFSaw.ar([8, 12], 0.2),	// non-band-limited sowtooth for filter source
			LFNoise1.ar([2, 3].choose, 1500, 1600),  // choose filter cutoff randomly
			0.05	// resonance quotient (low number = high resonance)
		)
	)
}).send(s);
)

a = Synth.new("ch2-ex2", target: s);

// Look at the waveform

s.scope;

a.free;

// Note that scope leaves a synth on the server. Don't worry about what it is now.
// It's needed to pass the audio to the window buffer.
// Closing the scope window makes that synth stop.

// Assignments: If you modify arguments to the UGens, you must recompile the synthdef
// so that the server knows about it before playing.


Link to this Page