Pit Stop 3

// frequenze in Hz
// ampiezze tra 0.0 e 1.0
// durate in secondi

(
s = Server.local.boot;
SynthDef(\sperc, {|freq =440, amp=0.5, dur=0.5, atk=10, gate=1.0|
                  var durms = dur*1000,
                      env   = EnvGen.ar(Env.perc(0.01, dur-0.01),gate,doneAction: 2),
                      osc   = SinOsc.ar(freq, 0, amp);
                  Out.ar(0, env *osc ! 2)
                  }).add;
) 

Loop 1

n.do({})

n = 10;                  // Numero
i = inf;                 // Infinito
a = [60,61,62,63,64,65]; // Array
//=====================================================================
// Numero

n.do({"ciao".postln});   // stampa 10 volte 'ciao'

(
n.do({arg i;             // contatore valutazioni, da 0
      i.postln
     }) 
)
//=====================================================================
// Array + 1 argomento

(
a.do({arg i;   // itera items
      i.postln})
)

// Array + 2 argomenti

(
a.do({arg i, id;     // items id
      [id,i].postln})// id items
)

// Array ...args

(
a.do({arg ...args;   // items id
      args.postln})
)
//=====================================================================
// Routine e Task
// .next e nextN()

(
r = Routine({
             n.do({arg i;
                   Synth("sperc");
                   i.yield
                   })
             })
)

r.next;     // uno alla volta
r.nextN(4); // n alla volta

// .play
(
Routine({
         n.do({arg i;
               i = 1/(i+1); // accel lineare...
               i.postln;
               Synth("sperc");
               i.wait;
             })
        }).play
)

// variante
(
Routine({
         n.do({arg i;
               i = (i+1).reciprocal; // .reciprocal
               i.postln;
               Synth("sperc");
               i.wait;
               })
         }).play
)

// 'inf' e .rrand()
(
r = Routine({
             i.do({var r = rrand(0.1,0.5); // rand(min,max)
                   r.postln;
                   Synth("sperc");
                   r.wait;                 // obbligatorio con 'inf'
                   })
             }).reset.play
)

r.stop;
//=====================================================================
// Parentesi tonde omesse

(
Routine{
        n.do{arg i;
             i = (i+1).reciprocal;
             Synth("sperc"); 
             i.wait;
             }
        }.play
)

loop{}

(
b = 120;
t = TempoClock(b/60);
r = Routine({
             loop{Synth("sperc"); 0.5.yield} 
             });
r.reset.play(t);
)

r.stop;

// Altra scrittura...

(
b = 120;
t = TempoClock(b/60);
r = Routine({
            {Synth("sperc"); 0.5.yield}.loop 
            });
r.reset.play(t);
)

r.stop;

if()

// if(test, {vero}, {falso}) il test e' un boolean

if(true, {"vero"}, {"falso"});  // ...vero
if(false,{"vero"}, {"falso"});  // ..falso

// rand(max) da 0 a max-1

if(rand(10).postln > 5, {"e' maggiore di 5"},{"e' minore di 5"});
if(rand(10) > 5, {Synth("sperc")},{"pausa"});

(
e = {
     loop{
          if(rand(10) > 5, {Synth("sperc")},{"pausa"}); 0.1.wait
          }
     }.fork;
)

e.stop;

Leggere collezioni

Tipi di collezioni

#[1,2,3,4,5]     // Literal array (non modificabili --CPU)
[1,2,3,4,5]      // Array         (size fisso       +-CPU)
Array[1,2,3,4,5] // Array
List[1,2,3,4,5]  // List          (size variabile   ++CPU)

Visualizzazioni

// [].plot (una finestra per Array)

#[12,34,56,3,78,98,23,9].plot;

// argomenti
(
a = #[12,34,56,3,78,98,23,9];
a.plot(name: "mio plot", // nome 
       bounds:540@200,   // dimensioni x@y in pixels
       minval: -100,     // valore limite inferiore
       maxval: 100,      // valore limite superiore
       discrete:true)    // true = punti, false = linee
)

// Array di Array (2d)
(
[#[0.1,0.5,0.6,0.1,0.9,0.3],
 #[1,5,2,4,8,10,5,6]].plot(minval:0,maxval:10);
)

//=====================================================================

// Plotter.new (una finestra per più visualizzazioni)

Plotter.new;
a = Plotter.new("segmenti",300@200); 
a.value = #[23,12,45,32,65]; 
a.value_(#[1,2,3]);  
a.value = #[10,2,33,41,50,23,45,56];

// Grafica (vale anche per le finestre generate con .plot)

(
a = Plotter("segmenti",300@200);
a.value = #[23,12,45,32,65];
a.setProperties(
    \backgroundColor, Color.black,  // sfondo
    \plotColor, Color.yellow,       // data
    \fontColor, Color.magenta,      // numeri
    \gridColorX, Color.white,       // griglia x
    \gridColorY, Color.white,       // griglia Y
                );
) 

Lettura

// {}.at(id)

a = #[1, 0.75, 0.25, 0.33, 0.33, 0.33, 0.5, 0.5]; // items
//    0  1     2     3     4     5     6    7     // indici sottointesi

a.at(0);  // 1
a.at(1);  // 0.75
a.at(2);  // 0.25
a.at(3);  // 0.33
a.at(-1); // nil
a.at(20); // nil

// Notazione Java

a[0]; // 1
a[1]; // 0.75
a[2]; // 0.25
a[3]; // 0.33 etc....

// [].size

a.size

// [].clipAt(), [].wrapAt() e [].foldAt()

(
a = #["a","b","c","d","e"];
n = 10;
3.do{arg biro;    // indici sottintesi
     a.at(biro).postln};
"-----------".postln;
n.do{arg biro;
     a.clipAt(biro).postln};
"-----------".postln;
n.do{arg biro;
     a.wrapAt(biro).postln};
"-----------".postln;
n.do{arg biro;
     a.foldAt(biro).postln};
)

Sequencing

// numero.do({arg ciao;})

(
10.do{
      arg ciao;   // numero di valutazioni   
      ciao.postln // stampa
      }
)

// Array.do({arg ciao;})
(
a = #["a","b","c"];
a.do{arg biro;       // 1 argomento: item
         biro.postln
    }
)

// Array.do({arg ciao miao;})
(
#["a","b","c"].do{arg ciao, miao;     // item id
	             [ciao, miao].postln}
)

// Array.do({arg ...args;})

(
a = #["a","b","c"];
a.do{arg ...args;       // argomenti: item, id
            args.postln // stampa
    }
)

// Sincronizzazione

(
var bpm,t,tsec,note,vels,durs,dt,r;
bpm  = 150;
t    = TempoClock(bpm/60);
tsec = 60/bpm;                
note = [90,      100,  98,   97,    96, 93].midicps;
vels = [60,       90, 120,   60,    40, 10]/127;
durs = [0.125, 0.125, 0.5, 0.25, 0.125,  1]*tsec;
dt   = [ 0.25,  0.25,   1,    1,     1,  1];

r = Routine({dt.do{arg delta, id;

                   Synth("sperc",[\freq, note.at(id), // frequenze richiamate come indici
                                  \amp,  vels.at(id), // ampiezze richiamate come indici
                                  \dur,  durs.at(id)  // durate richiamate come indici
                                 ]
                        );
                   delta.wait}                        // tempi delta richiamati come items
             }).reset.play(t);
)

Conversioni

// Tempo

(
var bpm, tsec;
bpm  = 150;                  // tempo relativo
tsec = 60/bpm;               // 1 beat in tempo assoluto (secondi)
tsec * [0.5,0.25,1,2,0.125]; // valori in frazioni del beat riscalati in tempo assoluto
)

// Altezze o frequenze

60.midicps;               // midi --> Hz
440.cpsmidi;              // Hz   --> midi

2.degreeToKey([0,2,5,7]); // il ricevente è l'indice (degree) della scala che spefichiamo come argomento
6.keyToDegree([0,2,3,6]); // il ricevente èil grado relativo tra gli indici

2.midiratio;              // midi --> fattore di moltiplicazione
1.6.ratiomidi;            // fatt.--> midi

440 * 1.midiratio;

// Intensità o ampiezze

64/127;       // velocity --> lineare
0.5*127;      // lineare  --> velocity
0.5.pow(4);   // lineare  --> quartica
0.0001.ampdb; // lineare  --> decibel
-80.dbamp;    // decibel  --> lineare

Pause

// Ampiezza = 0

(
var bpm, t, note, vels,dt,r;
bpm  = 120;
t    = TempoClock(bpm/60);
note = 72.midicps; 
vels = [80,80,80,0,80,80,0,80]/127;
dt   = 0.5;
r = Routine({
             vels.do({arg vel;
                      Synth("sperc",[\freq, note, \amp, vel]);
                      dt.wait
                     })
             }).play(t)
)

// Combinazione di tempi delta e durate

(
var bpm,t,note,tsec,durs,dt,r;
bpm  = 120;
t    = TempoClock(bpm/60);
tsec = 60/bpm;
note = 72.midicps;
durs = [1, 0.5, 0.25, 0.125, 0.25, 0.5, 1]*tsec; // Pause
// durs = [2,3,4,1,2,6];                         // Polifonia
dt   = 1;
r = Routine({
             durs.do({arg dur;
                      Synth("sperc",[\note, note, \dur, dur]);
                      dt.wait
                    })
             }).play(t)
)

Polifonia e Accordi

// Polifonia e contrappunto

(
var bpm, t, dt_a, dt_b, dt_c;
bpm  = 100;
t    = TempoClock(bpm/60);

dt_a = 0.125!32;
dt_b = 0.25!16;
dt_c = 0.5!8;

Routine({
         dt_a.do({arg delta;       // VOCE 1
                  Synth("sperc",[\freq, 88.midicps]);
                  delta.wait})
         }).play(t);
Routine({
         dt_b.do({arg delta;       // VOCE 2
                  Synth("sperc",[\freq, (66+rand2(3)).midicps]);
                  delta.wait})
         }).play(t);
Routine({
         dt_c.do({arg delta;       // VOCE 3
                  Synth("sperc",[\freq, (48+rand2(3)).midicps]);
                  delta.wait})
         }).play(t);
)


// Armonia e accordi = Array bidimensionali (2D)

(
var bpm,t,tsec,note,vels,durs,dt,r;
bpm  = 60;
t    = TempoClock(bpm/60);
tsec = 60/bpm;                // conversione unità da tempo relativo a assoluto
note = [[90,93], 100,  [98,99,102,100],   97,    96, [93,89,87]].midicps;
vels = [ 60,      90,               70,   90,    80,         70]/127;
durs = [ 0.25,  0.25,                1,    1,     1,          1]*tsec;
dt   = [ 0.25,  0.25,                1,    1,     1,          1];

r = Routine({dt.do{arg delta, id;
	               var n = note.at(id);                // singoli item di 'note'

                   if(n.size==0,                           // ...se è un valore:
                      {Synth("sperc",[\freq, n,            // note singole
                                      \amp,  vels.at(id),
                                      \dur,  durs.at(id)])
                       },
                                                           // ...se è un Array:
                      {n.size.do({arg i;                   // loop (accordi)
                                  Synth("sperc",[\freq, n.at(i),
                                                 \amp,  vels.at(id),
                                                 \dur,  durs.at(id)])
                                })
                      }
                      );
                  delta.wait}                        // tempi delta
             }).reset.play(t)
)

Random 1

// tra boolean

0.5.coin;       // 50% = true, 50% = false
0.5.coin.asInt; // true = 1, false = 0;

// tra due limiti

rand(8);      // tra 0 e n-1
rand2(1.0)    // tra +/- n
rrand(20,50); // tra min e max

// tra un insieme di valori

[87,78,76,45,23].choose;
[0.1,0.9,1].choose;
1/[2,3,4,8].choose;

// senza ripetizioni: items

(
var a, bpm;
a   = [60,61,62,63,64,65,66,67,68,69,70,71].scramble;
bpm = 120;

t = TempoClock.new(bpm/60);
r = Routine.new({
                 a.do({arg item;
                       Synth(\sperc,[freq:item.midicps, amp: 0.5]);
                       0.25.wait
                       })
}).play(t)
)

// senza ripetizioni: indici

(
var items, idx, bpm;
items   = [98,100,76,73,89,103];          // altezze
idx     = [0, 1,  2, 3, 4, 5  ].scramble; // indici
bpm = 120;

t = TempoClock.new(bpm/60);
r = Routine.new({
                 idx.do({arg id;
                         Synth(\sperc,[freq:items.at(id).midicps,
                                        amp: 0.5]);
                         0.25.wait
                         })
}).play(t)
)