Friday, December 12, 2014

Last Week's Notes

Note: This is here temporarily for the benefit of some students. It will move to Moodle and disappear form here


/*
SuperCollider is an Object Oriented Language that is designed for music and audio. It is a Music V type language. that means, like MAX MSP, the sound generation runs on a different thread than the control stuff. In MAX / MSP, you see this represented by differented coloured patch connections. In SuperCollider, audio runs on a server.

Because we don't have much time, I'm going to ask you take notes and then try stuff out later, not in class.  I also will ask Pieman to put a tutorial up for you on Moodle.

Hopefully you all have SuperCollider installed. When you tried opening it, you saw the screen divided in two parts. One part was the post window, filled with strange text and the other part was just blank and called untitled. The untitled window is where you write your code.  When you want to run your code, you select it with your mouse and hit ctrl-enter if you are in windows or linux, or apple-enter if you are on a mac. On some computers, you may need to use the apple or control key on the right wide of your keyboard. Try this out later with a simple program:
*/

4 + 4

/*
When you highlight 4 + 4 and run it, 8 will print out in your post window.

We're going to start out with working with sound design. Sound runs on the server. Therefore, we need to fist boot the server.  There are a few ways to do this. If you look in the Language menu, one of the items is 'boot server'. Select that.

The text in the little status bar at the bottom should change and turn green. you will also see output in the post window.


Now that the server is booted, let's make some sound:

*/

(
SynthDef(\sine, {
 Out.ar(0,
  SinOsc.ar(440, 0, 0.2)
 )
}).play
)

/*
When you want it to stop, hit ctrl-period or apple-period.

We are defining a SynthDef, sending it to the server and telling it to play. a synthDef is a description of how the server makes a sound.

First it has the name, which starts with a \, then comman curly bracket, then all of the UGens.

Out.ar is where the sound should come out. The channels start with 0, so this is on the left. Next is what should come out.
SinOsc is a sinwav oscillator. It's running at 440 Hz, it's phase is 0, and it's amplitude is 0.2.
Notice that these items have commas between them.

Then we close all of our open parens and curly brackets

Then a .play tells the whole thing to play.


We can organise this better using variables.
A variable is a container with a name. Like a box named sine. It can hold an object.
*/

(
SynthDef(\sine, {
 var sine;
 sine = SinOsc.ar(440, 0, 0.2);
 Out.ar(0, sine);
}).play
)


/*

First we let SuperCollider know that we've got a variable named sine.
We end that with a semicolon, so it knows that statement is done.

Then we do an assignment. Don't read = as 'equals, read it as 'gets'.
sine gets SinOac.ar.  We've got a box named sine. We've put a sine oscillator in the box, to keep track of it.
Then a semi colon, so it knows we're done with the assignment.
Then Our.ar, saying what channel to go out on.  And we tell it, put out whatever's in sine. Take the contents of the box and send it to the left speaker.


Every line needs to be separated by semicolons. Later on, when you can't figure out why something isn't working, check the semi colons first. It's the most common mistake. I still forget them all the time.


These sines all last forever, so let's try an envelope:

*/


(
SynthDef(\sinenv, {
 var sine, env;
 sine = SinOsc.ar(440, 0, 0.2);
 env = EnvGen.kr(Env.perc, doneAction:2);
 Out.ar(0, sine * env);
}).play
)


/*
we have added an extra variable called env
We've put an EnvGen into it. env gets EnvGen.kr.  An EnvGen is an envelope generator. First we tell it what envelope shape, then we do this doneAction:2 thing.

When we're telling out what to play, we tell it to multiple the sine box by the env box.


Let's do some ring modulation:

*/

(
SynthDef(\sinerm, {
 var sine, ringmod, env;
 sine = SinOsc.ar(440, 0, 0.2);
 ringmod = SinOsc.ar(30) * sine;
 env = EnvGen.kr(Env.perc, doneAction:2);
 Out.ar(0, ringmod * env);
}).play
)


/*

We've added a new variable called ringmod.

Ring mod gets a new sinosc times the contents of the sine variable.
When SuperCollider is looking at your code and it sees an assignment - the equals sign - it does everything on the right hand side of the assingment and puts the result of everything into the variable on the left.

We've picked 30 Hz, because that's the frequency daleks use, but what if we want different frequencies?

We could keep changing the synthdef:
*/

(
SynthDef(\sinerm, {
 var sine, ringmod, env;
 sine = SinOsc.ar(470, 0, 0.2);
 ringmod = SinOsc.ar(30) * sine;
 env = EnvGen.kr(Env.perc, doneAction:2);
 Out.ar(0, ringmod * env);
}).play
)

(
SynthDef(\sinerm, {
 var sine, ringmod, env;
 sine = SinOsc.ar(810, 0, 0.2);
 ringmod = SinOsc.ar(30) * sine;
 env = EnvGen.kr(Env.perc, doneAction:2);
 Out.ar(0, ringmod * env);
}).play
)

(
SynthDef(\sinerm, {
 var sine, ringmod, env;
 sine = SinOsc.ar(752, 0, 0.2);
 ringmod = SinOsc.ar(30) * sine;
 env = EnvGen.kr(Env.perc, doneAction:2);
 Out.ar(0, ringmod * env);
}).play
)

/*

Or, we could use a special kind of variable called an argument

*/

(
SynthDef(\sinermarg, { arg freq;
 var sine, ringmod, env;
 sine = SinOsc.ar(freq, 0, 0.2);
 ringmod = SinOsc.ar(30) * sine;
 env = EnvGen.kr(Env.perc, doneAction:2);
 Out.ar(0, ringmod * env);
}).add
)

/*

We've declared the argument at the top. That uses the keyword arg. argument need to go before variables.
So first you have the SynthDef and the name of it and the culry bracked.
Then next is arguments, starting with the keyword arg.
then are the variables, starting with the keyword var.
Everything else is below that.


It does not make sound when we play this one, because we changed the .play at the end to .add.

Instead of playing this right away, we tell the server to remember it, so we can play it later.

*/

Synth(\sinermarg, [\freq, 440])


/*
there are a lot of ways we can play a SynthDef, and one of them is by via Synth.

The first argument to Synth is \sinermarg, which is the name of the synthdef.  The next is this square bracket thing.

The first thing in the square brackets is \freq, this is the name of our argument, but starting with a slash.
Then is the value we want to give it.

*/


Synth(\sinermarg, [\freq, 860])

/*

What if we want to have more arguments?

*/

(
SynthDef(\sinermargs, { arg freq, rm, dur, amp;
 var sine, ringmod, env;
 sine = SinOsc.ar(freq, 0, amp);
 ringmod = SinOsc.ar(rm) * sine;
 env = EnvGen.kr(Env.sine(dur), doneAction:2);
 Out.ar(0, ringmod * env);
}).add
)

Synth(\sinermargs, [\freq, 912, \rm, 123, \dur, 7, \amp, 0.3])



/*

For this morning, we're going to focus more on SynthDefs, so we'll get to do sequences of notes in the afternoon.


Let's try different waves, panned to centre
*/


(
SynthDef(\saw, { arg freq, dur, amp;
 var saw, env, panner;
 saw =  Saw.ar(freq, amp);
 env = EnvGen.kr(Env.sine(dur), doneAction:2);
 panner = Pan2.ar(saw, 0,env);
 Out.ar(0, panner);
}).add
)

Synth(\saw, [\freq, 550, \dur, 3, \amp, 0.2])


/*

Notice that saw and sign have different arguments in their list. the second thing in the list to sign is a 0 and the amplitude is third. But saw just goes directly from frequency to amplitude.

How would you know about how these are different (or even what the various oscillators are)?  the answer is in the help browser!

Under the Help menu, there is a 'show help browser' option. You can click on search there to start searching. Or just browse around. Get to know the help browser. It is your friend. There are lots of examples.

Let's try some filtered noise:

*/


(

SynthDef(\subtractive, { arg freq, dur, amp;
 var noise, filt, env, panner;
 noise = WhiteNoise.ar;
 filt = RLPF.ar(noise, freq);
 env = EnvGen.kr(Env.sine(dur), doneAction:2);
 panner = Pan2.ar(filt, 0,env * amp);
 Out.ar(0, panner);
}).add
)

Synth(\subtractive, [\freq, 1200, \dur, 3, \amp, 0.2])


/*
WhiteNoise is just noise, so there's no need to give it additional information
RLPF is a Resonant Low Pass Filter

You may have noticed some of these are .ar and some are .kr.
ar is audio rate
kr is control rate

The envelope doesn't need to change values as often as a 440 Hz sine oscillator in order to sound good. The oscillator needs to go through it's entire wave form 440 times a second, whereas, the envelope needs much less precision.

*/


/*

This file is a SuperCollider file.  The english text is in a comment.  Programmers sometimes want to put human-language notes in their files.  This makes the files more readable to humans, but the text is not meaningful to SuperCollider. They mark the text as not being code by putting comment markers around it. Every one of these block of text starts with a slash star and ends with a star slash.
*/


/* <-- this is the starts of a comment
this is the end of a comment ---> */

// <- this marks a comment that only lasts for one line (and thus does not need an end marker)




Pbind Notes from this morning

Note: This is here temporarily for the benefit of some students. It will go up on Moodle and then be removed from here.


/*

Now what we want is a way to play notes in sequence. Let's use an earlier synthdef:

*/

(
SynthDef(\sin, { arg freq = 440, dur = 1, amp= 0.5, pan=0;
 var sine, env, panner;
 sine = SinOsc.ar(freq, 0, amp);
 env = EnvGen.kr(Env.perc(0.01, dur), doneAction:2);
 panner = Pan2.ar(sine, pan, env);
 Out.ar(0, panner);
}).add
)


(

Synth(\sin, [\freq, 440, \dur, 1, \amp, 0.3]);
Synth(\sin, [\freq, 550, \dur, 1, \amp, 0.3]);
Synth(\sin, [\freq, 660, \dur, 1, \amp, 0.3]);

)

/*

This plays all at once!

Fortunately, there are several ways to add timings.  One of these is Pbind.

*/


Pbind.new.play


/*

As before, press cntl-. or apple-. to stop

Pbind makes a LOT of assumptions on your behalf, so you can run it with no arguments at all.  Or you can specify as much as you want.

Let's tell it to use our synthdef:

*/

(

Pbind(
 \instrument, \sin
).play


)


/*

Let's tell it to play louder

*/

(

Pbind(
 \instrument, \sin,
 \amp, 0.5
).play


)


// Change the freq and dur

(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \freq, 770,
 \dur, 0.5
).play


)

/*

  This is better, but let's make the notes change over time


*/


(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \freq, Pseq([440, 550, 660, 770, 880], 1),
 \dur, 0.5
).play


)


/*

Pseq plays all the array contents in order, then repeats the number of times listed

*/


(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \freq, Pseq([440, 550, 660, 770, 880], 3),
 \dur, 0.4
).play


)


/*
To repeat forever, use the keyword inf

*/

(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \freq, Pseq([440, 550, 660, 770, 880], inf),
 \dur, 0.2
).play


)


/*


We can use Pseqs for ANY item in a Pbind

*/


(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \freq, Pseq([440, 550, 660, 770, 880], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 2)
).play


)


/*

The first Pseq that ends, ends the entire Pbind



Instead of specifying frequencies let's switch to scale degrees

*/


(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \degree, Pseq([0, 2, 4, 6, 7], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 2)
).play


)



/*

The Pbind does the maths for us to map the scale degrees to the frequency.  This works because our synth uses the argument freq for frequency. the Pbind assumes this is what the frequency argument will be called and acts accordingly.


We can change to a different number of scale steps

*/

(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \stepsPerOctave, 10,
 \degree, Pseq([0, 2, 4, 6, 7], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 2)
).play


)



/*

We can change scales

*/

(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \scale, Scale.minor,
 \degree, Pseq([0, 2, 4, 6, 7], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 2)
).play

)
/*

Look up scales in the help browser for more

(incidentally, when you want to search, the search box at the top right searches only the currently displayed page.  to search everything, click on the word 'search' on the top.



We can do maths with Pseqs

*/

(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \scale, Scale.minor,
 \degree, Pseq([0, 2, 4, 6, 7], inf) + Pseq ([0, 0, 0, 0, 0, 5, 5, 5, 5], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10)
).play

)


/*

We can nest Pseqs

*/


(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \scale, Scale.minor,
 \degree, Pseq([0, 2, 4, 6, 7], inf) +
 Pseq ([
  Pseq([0], 5),
  Pseq([5], 4)
 ], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10)
).play

)

/*

They can also be multiplied, divided, etc.



We can play multiple notes at once:

*/


(

Pbind(
 \instrument, \sin,
 \amp, 0.3,
 \scale, Scale.minor,
 \degree, Pseq([[1, 3], [3, 5, 7], [2, 5], 7, [1,8]], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 2)
).play

)


/*

If a pseq gets an array back for any value, it will make as many notes as are in the array, each with one of the values in the array.

So when it gets [3, 5, 7] for the degree, it makes one note with the 3rd, one with the 5th and one with the 7th.




We can not always use direct sequences

*/


(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \scale, Scale.minor,
 \degree, Prand([0, 2, 4, 6, 7], 3),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 2)
).play

)


/*

Prand picks an item randomly from the array, the amount of times you tell it to. So rather than playing through everything 3 times, it picks 3 items

*/

(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \scale, Scale.minor,
 \degree, Prand([0, 2, 4, 6, 7], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 2)
).play

)


/*

Prands can do all the same maths as Pseqs and work in combination with them

*/




(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \scale, Scale.minor,
 \degree, Prand([0, 2, 4, 6, 7], inf)  + Pseq ([0, 0, 0, 0, 0, 5, 5, 5, 5], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10)
).play

)

(

Pbind(
 \instrument, \sin,
 \amp, 0.3,
 \scale, Scale.minor,
 \degree, Prand([0, 2, 4, 6, 7, [1, 3, 5]], inf)  + Pseq ([0, 0, 0, 0, 0, 5, 5, 5, 5], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10)
).play

)



(

Pbind(
 \instrument, \sin,
 \amp, 0.3,
 \scale, Scale.minor,
 \degree, Prand([0, 2, 4, 6, 7, [1, 3, 5]], inf)  + Pseq ([
  Pseq([0], 5),
  Pseq([5], 4),
  Prand([0, 2, 5], 1)
 ], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10)
).play

)

/*

Pwhite varies randomly between a low and a high number

*/

(

Pbind(
 \instrument, \sin,
 \amp, 0.3,
 \scale, Scale.minor,
 \degree, Prand([0, 2, 4, 6, 7, [1, 3, 5]], inf)  + Pseq ([
  Pseq([0], 5),
  Pseq([5], 4),
  Prand([0, 2, 5], 1)
 ], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10),
 \pan, Pwhite(-1, 1, inf)
).play

)

/*
The panning is hard left, hard right or center, because it's only picking whole number. If we want it to pick numbers between the whole numbers, we need to specify that

*/

(

Pbind(
 \instrument, \sin,
 \amp, 0.3,
 \scale, Scale.minor,
 \degree, Prand([0, 2, 4, 6, 7, [1, 3, 5]], inf)  + Pseq ([
  Pseq([0], 5),
  Pseq([5], 4),
  Prand([0, 2, 5], 1)
 ], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10),
 \pan, Pwhite(-1.0, 1.0, inf)
).play

)




/*

The whole numbers are called intergers and the numbers with decimal points are called floating point or floats, which are terms you might see in the help files.

*/

/*

This behaviour is actually useful, if we want to pick scale degrees, we may not what to pick ones in between

*/

(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \scale, Scale.minor,
 \degree, Pwhite(0, 8, 10),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10),
 \pan, Pwhite(-1.0, 1.0, inf)
).play

)


(

Pbind(
 \instrument, \sin,
 \amp, 0.5,
 \scale, Scale.minor,
 \degree, Pwhite(0.0, 8.0, 10),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10),
 \pan, Pwhite(-1.0, 1.0, inf)
).play

)

/*

What if we want moments of silence?

we use the symbol \rest for the freq or degree

*/

(

Pbind(
 \instrument, \sin,
 \amp, 0.3,
 \scale, Scale.minor,
 \degree, Pseq([0, 2, \rest], 3),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10),
 \pan, Pwhite(-1.0, 1.0, inf)
).play
)
(

Pbind(
 \instrument, \sin,
 \amp, 0.3,
 \scale, Scale.minor,
 \degree, Prand([1, 3, 5, 7, 8, [1, 3, 5], \rest], inf)  + Pseq ([
  Pseq([0], 5),
  Pseq([5], 4),
  Prand([0, 2, 5], 1)
 ], inf),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10),
 \pan, Pwhite(-1.0, 1.0, inf)
).play

)

/*

What if we want to do one thing and go on to another thing?

*/

(
Pseq([
 Pbind(
  \instrument, \sin,
  \amp, 0.3,
  \scale, Scale.minor,
  \degree, Prand([1, 3, 5, 7, 8, [1, 3, 5], \rest], inf)  + Pseq ([
   Pseq([0], 5),
   Pseq([5], 4),
   Prand([0, 2, 5], 1)
  ], inf),
  \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 2),
  \pan, Pwhite(-1.0, 1.0, inf)
 ),
 Pbind(
  \instrument, \sin,
  \amp, 0.3,
  \stepsPerOctave, 10,
  \degree, Pwhite(1, 10, 10),
  \dur, Prand([0.4, 0.6, 0.8], inf)
 )
]).play
)

(
Pseq([
Pbind(
 \instrument, \sin,
 \amp, 0.3,
 \scale, Scale.minor,
 \degree, Pseq([0, 2, \rest], 3),
 \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10),
 \pan, Pwhite(-1.0, 1.0, inf)
),
 Pbind(
  \instrument, \sin,
  \amp, 0.3,
  \stepsPerOctave, 10,
  \degree, Pwhite(1, 10, 10),
  \dur, Prand([0.4, 0.6, 0.8], inf)
 )
]).play


/*

What if we don't just want chords, but want two streams going at once?

*/
(
SynthDef(\crapSnare, { arg amp, pan;
 var noise, env, panner;

 noise = WhiteNoise.ar;
 env = EnvGen.kr(Env.perc, doneAction:2);
 panner = Pan2.ar(noise, pan, env);
 Out.ar(0, panner * amp)
}).add
)

(
Ppar([
 Pbind(
  \instrument, \sin,
  \amp, 0.3,
  \scale, Scale.minor,
  \degree, Prand([1, 3, 5, 7, 8, [1, 3, 5], \rest], inf)  + Pseq ([
   Pseq([0], 5),
   Pseq([5], 4),
   Prand([0, 2, 5], 1)
  ], inf),
  \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10),
  \pan, Pwhite(-1.0, 1.0, inf)
 ),
 Pbind(
  \instrument, \crapSnare,
  \amp, 0.2,
  \dur, 0.8
 )
]).play
)

// note the snare never stops!

// or moving the snare to the offbeat:




(
Ppar([
 Pbind(
  \instrument, \sin,
  \amp, 0.3,
  \scale, Scale.minor,
  \degree, Prand([1, 3, 5, 7, 8, [1, 3, 5], \rest], inf)  + Pseq ([
   Pseq([0], 5),
   Pseq([5], 4),
   Prand([0, 2, 5], 1)
  ], inf),
  \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10),
  \pan, Pwhite(-1.0, 1.0, inf)
 ),
 Pbind(
  \instrument, \crapSnare,
  \amp, 0.2,
  \dur, Pseq([0.4, Pseq([0.8], inf)], 1)
 )
]).play
)


/*
to get rid of the first beat, we need to give it a rest for the freq.
It does not matter that the synthDef doesn't take freq as an argument. This is just for the safe of the pbind

*/


(
Ppar([
 Pbind(
  \instrument, \sin,
  \amp, 0.3,
  \scale, Scale.minor,
  \degree, Prand([1, 3, 5, 7, 8, [1, 3, 5], \rest], inf)  + Pseq ([
   Pseq([0], 5),
   Pseq([5], 4),
   Prand([0, 2, 5], 1)
  ], inf),
  \dur, Pseq([0.2, 0.2, 0.4, 0.2, 0.6], 10),
  \pan, Pwhite(-1.0, 1.0, inf)
 ),
 Pbind(
  \instrument, \crapSnare,
  \amp, 0.2,
  \dur, Pseq([0.4, Pseq([0.8], inf)], 1),
  \freq, Pseq([\rest, Pseq([440], inf)], 1),
 )
]).play
)

/*

Ppars can also be nested in Pseqs.
The helpfiles for streams patterns and events go into loads of detail about how to use p-things


When you are making your own pbinds, watch out for forgetting commas in the middle of them, or dangling commas at the end. commas should go between items.

*/


/* Finally, we might have a synth that lasts for a really long time, that we want to change, but not end
*/

(
SynthDef(\sinerm, {arg freq, amp;
 var sine, ringmod, env;
 sine = SinOsc.ar(freq, 0, 0.2);
 ringmod = SinOsc.ar(30) * sine;
 Out.ar(0, ringmod * amp);
}).play
)

(

Pmono(\sinerm,
 \degree, Pwhite(0, 12, inf),
 \amp, 0.5,
 //\stepsPerOctave, 10,
 \db, -3
).play

)


// We can change the synthdef a bit to add some lag

(
SynthDef(\sinermlag, {arg freq, amp;
 var sine, ringmod, env, lag;
 lag = Lag.kr(freq);
 sine = SinOsc.ar(lag, 0, 0.2);
 ringmod = SinOsc.ar(30) * sine;
 Out.ar(0, ringmod * amp);
}).play
)



(

Pmono(\sinermlag,
 \degree, Pwhite(0, 10, inf),
 \amp, 0.5,
 \stepsPerOctave, 10,
 \db, -3 // Pmono and Pbind will translate db to amp for us
).play

)


/*

Algorave:  uses algorythms to generate dance music
Can be live-coded, but need not be

Examples:

Microrex https://soundcloud.com/micorex
Yee-king http://open.spotify.com/track/1UTiLOe4LwarRDWR5pmjZg
Norah Lorway http://earthrid.bandcamp.com/album/ive-had-dreams-like-this

*/

Some Notes for Students Today

Note: This is literally for some students I have today. It will appear on Moodle some time soon and then disappear from this space.


/*

Extra Things!



Q: How do you make a Pmono stop?

A: A Pmono stops when it runs out of values, to send, just like a Pbind. However, unless we tell a synth to stop, it will keep going forever.



Q: How do you tell a synth to stop?

A: Envelopes!  We've seen this already with fixed duration envelopes. But if we don't know from the start how long we want the synth to go for, when need to use a different kind of envelope.

For example, and ASR.

ASR stands for 'attack, sustain, release and is a very common envelope in electronic music.  It uses a 'gate' to know when to start and stop. When the gate is 1, the envelope starts doing the attack, then it sustains indefinitely. As soon as the gate changes to 0, it immeditately stops whaever its doing to do the release portion.

Ex:

*/
(
SynthDef(\blipGate, {|freq, amp, gate=1, pan|  // the vertical bars are equvalent to using the keyword arg
 var blip, panner, env;
 blip = Blip.ar(freq, 10, 0.2);
 env = EnvGen.kr(Env.asr, gate, doneAction:2); // look at the helpfile for Env for more
 panner = Pan2.ar(blip, pan, env);
 Out.ar(0, panner * amp);
}).add
)

(
Pmono(
 \blipGate,
 \pan, Pwhite(0.0, 1.0, 5),
 \degree, Pwhite(1, 4, 5)
).play
)


// gates also work with Pbinds

(
Pbind(
 \instrument, \blipGate,
 \pan, Pwhite(0.0, 1.0, 5),
 \degree, Pwhite(1, 4, 5)
).play
)

/*

Q: How can I make frequency changes less abrupt?

A:  Add in some lag:

*/

(
SynthDef(\blipLag, {|freq, amp, gate=1, pan|  // the vertical bars are equvalent to using the keyword arg
 var lag, blip, panner, env;
 lag = Lag.kr(freq);
 blip = Blip.ar(lag, 10, 0.2);
 env = EnvGen.kr(Env.asr, gate, doneAction:2); // look at the helpfile for Env for more
 panner = Pan2.ar(blip, pan, env);
 Out.ar(0, panner * amp);
}).add
)

(
Pmono(
 \blipLag,
 \pan, Pwhite(0.0, 1.0, 5),
 \degree, Pwhite(1, 4, 5)
).play
)




/*

Q: If you're live coding and want to change a pbind without stopping it, can you do that?

A: Yes, with Pdef

*/

(
Pdef(\blips,
 Pbind(
  \instrument, \blipGate,
  \pan, Pwhite(0.0, 1.0, inf),
  \degree, Pwhite(1, 4, inf),
  \dur, 0.4
 )
).play
)

// just put a Pdef around the pbind



// now, let's change without stopping

(
Pdef(\blips,
 Pbind(
  \instrument, \blipGate,
  \pan, Pwhite(0.0, 1.0, inf),
  \degree, Pwhite(1, 4, inf),
  \dur, Prand([0.4, 0.2, 0.2, 0.8], inf)
 )
).play
)


// another change

(
Pdef(\blips,
 Pbind(
  \instrument, \blipGate,
  \pan, Pwhite(0.0, 1.0, inf),
  \degree, Pwhite(1, 4, inf) * Pwhite(1, 2),
  \dur, Prand([0.4, 0.2, 0.2, 0.8], inf)
 )
).play
)



Pdef(\blips).fadeTime = 5; // tell it to fade changes in and out over 5 seconds

Pdef(\blips).stop; // tell it to stop (but don't stop anything else, including other Pdefs)


/*

Q: what are some good oscillators?

A:

SinOsc
Blip
Formant
Pulse
Saw
Klank

// look at the help files for those


Ok, now I want you folks to get to work making some sounds and patterns. I'll come around to answer questions, or you can pair up if you want.

*/