/*
***********************************************************************************
HW1 Solution - Problem 2
Piano Phase by Steve Reich (Using Bindings)
Created by Juan-Pablo Caceres, January 2007
Under Subversion Control System
***********************************************************************************
*/
s = Server.default.boot;
//Very simple Piano SythDefs for be use.
//Piano1 is on the left channel
//Piano2 is on the right channel
//----------------------------------------------------------
(
SynthDef("pianophase1",
{ arg out=0, freq=440, sustain=0.05;
var env;
env = EnvGen.kr(Env.perc(0.01, sustain, 0.2), doneAction:2);
Out.ar(out, SinOsc.ar(freq, 0, env))
}).store;
SynthDef("pianophase2",
{ arg out=1, freq=440, sustain=0.05, amp=0.1;
var env;
env = EnvGen.kr(Env.perc(0.01, sustain, 0.2), doneAction:2);
Out.ar(out, SinOsc.ar(freq, 0, (amp*env)))
}).store;
)
/*
To use another than the default SynthDef, we need to read the synth
description library so that event know's what kind of arguments there
are in each SynthDef. Use .store (instead of load or send) to create
a Synth Description (SynthDesc).
*/
SynthDescLib.global.read;
//Define a funtion to convert tempo from BPM to sec.
//--------------------------------------------------
(
~bpm2sec = {arg tbpm;
var tsec;
tsec = 60/tbpm;
};
)
//Parameters and Pattern calculations
//----------------------------------
(
~tempoBPM = 72; //global tempo (from score)
//tempo in seconds for each pitch (1/8 notes)
~tempo = ~bpm2sec.value(~tempoBPM)/6;
//Here we incorporata the variable ~phasing_measures that is how many measures
//the phasing process takes;
~phasing_measures = 5;
p = ~phasing_measures*12; n = p+1;
~phasetime = p/n;
~nphase = 3; //<-- this is the number of measure to play in phase
//Now we decide the number of measures that piano 2 waits before starting
//We will use this number in Ptpar when we play the piece
~nmeasures_piano2_wait = 1;
//Now we need to compute the number of measures that are needed in order to make the piece stop
//after all the 12 transpositions
//The total lenght (in measures) of the piece will be:
~total_measures = ~nmeasures_piano2_wait +
((~nphase + ~phasing_measures)*12) + //all the twelve transpositions
~nphase; //last repetition locked
//Now we use this number to create out patters
//Pitches for one measure (pattern)
~notes = Pseq(#[64, 66, 71, 73, 74, 66, 64, 73, 71, 66, 74, 73].midicps, ~total_measures);
//We now create the patter of tempo for Piano 2
//We have to modify this pattern from the class example in order to
//compute the exact number of measure and then stop at the end of the piece.
//We do this by just adding an extra pattern with the last measure that is
//in melodic and rythmic sinc. (embeding patterns into patterns)
~p2tempoPatter = Pseq([
Pseq([
Pseq(Array.fill(12,1), ~nphase),//<-- number of measure to play in phase
Pseq(Array.fill(n,~phasetime))]//<-- this is the phase array
,12*(~total_measures - ~nmeasures_piano2_wait - ~nphase)), //rememeber that piano2 waits to start,
Pseq(Array.fill(12,1), ~nphase)]); //so we have to substract those measures here
//Fianlly we create the amplitude envelope Pattern
//For that, we use the Env.triangle, and we construct a pattern that is very similar to ~p2tempoPatter
//but with the values of the envellope.
//Triangle envelope to use in amplitude for Phasing
~triEnv = Env.triangle(dur:1, level: 3);
//Amplitude Envelpe Patter
~p2ampPatter = Pseq([
Pseq([
Pseq(Array.fill(12,1), ~nphase),//<-- number of measure to play in phase
Pseq(~triEnv.asSignal(n)+1)]//<-- this is the phase array
,12*(~total_measures - ~nmeasures_piano2_wait - ~nphase)), //rememeber that piano2 waits to start,
Pseq(Array.fill(12,1), ~nphase)]);
)
//Play the piece
//--------------------------------
(
~piano1 = Pbind(
\instrument, "pianophase1",
\out, 0,
\freq, ~notes,
\dur, ~tempo
);
~piano2 = Pbind(
\instrument, "pianophase2",
\out, 1,
\freq, ~notes,
\dur, ~tempo*~p2tempoPatter,
\amp, ~p2ampPatter
);
//let's start piano2 three measures after piano1 starts
~piece = Ptpar([0, ~piano1, ~nmeasures_piano2_wait*~tempo*12, ~piano2]).play;
)