Friday, December 12, 2014

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

*/

No comments: