ChucK 101 – Lezione 3: Questione di tempo

È passato un po’ di tempo dalla seconda lezione e, ormai, dovreste aver acquisito una certa familiarità con le variabili e i tipi di dati in ChucK. Negli esempi che abbiamo fatto visto fino a oggi abbiamo usato una parola chiave che non abbiamo mai approfondito: now.

In ChucK, così come in tutti i linguaggi di programmazione, esistono delle parole chiave che sono “riservate” perché permettono al linguaggio stesso di funzionare e, quindi, non possono essere usate per attribuire a variabili create dall’utente quel nome specifico. Ad esempio, non possiamo creare una variabile di nome now perché per il compilatore quella parola ha già un significato ben preciso. La regola generale dice che tutte le parole che dentro miniAudicle vengono colorate, sono parole chiave riservate.

La variabile di durata “dur”

Possiamo utilizzare la parola chiave dur per determinare delle variabili di durata. Riprendiamo l’ultimo esempio fatto nel precedente post (quello con le variabili di tipo float) e aggiungiamo delle variabili di durata.

/*
 * Chuck 101 - Lezione 3
 * Questione di tempo
 */
 SinOsc sine => dac;
// Middle C (in Hz)
 261.626 => float myFrequency;
// Volume as a variable
 0.6 => float myVolumeOn;
 0 => int myVolumeOff;
// Variabili di durata
 0.50::second => dur onDuration;
 0.75::second => dur offDuration;
// Suoniamo una nota
 myFrequency => sine.freq;
 myVolumeOn => sine.gain;
 onDuration => now;
myVolumeOff => sine.gain;
 offDuration => now;
// Suoniamo un'altra nota al doppio della frequenza
 2 *=> myFrequency;
myFrequency => sine.freq;
 myVolumeOn => sine.gain;
 onDuration => now;
myVolumeOff => sine.gain;
 offDuration => now;

Analizziamo il codice che abbiamo appena scritto: all’inizio del programma abbiamo deciso di utilizzare un’oscillatore con onda sinusoidale a cui abbiamo assegnato una frequenza pari a 261.626 Hz (Do centrale); abbiamo due variabili di volume: la prima a 0.6 (nota ON) e la seconda a 0 (nota OFF). Nel primo caso abbiamo utilizzato una variabile float in quanto il valore è decimale, nel secondo caso una variabile di tipo integer. Abbiamo dichiarato due variabili di durata utilizzando la parola chiave dur.

Nelle blocco di codice tra le righe 18 e 24, facciamo suonare al nostro oscillatore una nota per 0.5 secondi per poi fare una pausa (impostando il gain a 0) di 0.75 secondi. Nel blocco dalla riga 26 alla fine del progetto, ripetiamo la stessa operazione raddoppiando, però, la frequenza riprodotta.

Altre variabili di tempo

Oltre a now durin ChucK sono previste altre parole chiave di tempo:

samp che corrisponde a 1 sample digitale e dipende dalla frequenza di campionamento (normalmente 1 sample equivale a 1/44100 di secondo), ms ovvero millisecondi, second per i secondi, minute per i minuti, hour per le ore, day per i giorni, week per le settimane. Mancano le variabili “mesi” e “anni” perché, come ben sappiamo, posso avere durate diverse (mesi di 28, 30 o 31 giorni e anni di 365 o 366 giorni).

Questione di tempo

Nel post introduttivo avevo accennato all’importanza del tempo in ChucK. Non dobbiamo dimenticare che senza lo scorrere del tempo il suono e, di conseguenza, la musica non potrebbero esistere. Grazie alla lezione di oggi, abbiamo scoperto che in ChucK possiamo cominciare a manipolare il tempo a nostro piacimento.

Cose importanti da ricordare:

  • le variabili di tempo durata sono native in ChucK (come le variabili integerfloat).
  • la variabile now rappresenta sempre il tempo corrente in ChucK (riparte ogni volta da 0 quando avviamo la Virtual Machine).
  • l’unico modo per far scorrere il tempo in ChucK è manipolare la variabile now.

Dal momento che le variabili di tempo e durata sono native, possiamo ovviamente seguire operazioni matematiche tra di esse per creare nuove variabili di tempo.

2::second + 1::minute => dur newDur;

Nella musica “suonata” il tempo viene contatto in BPM (Beats Per Minute) e non in secondi. Come ovviare a questo problema? Creando delle variabili come nell’esempio seguente:

// Impostiamo i quarti (seminima) a 0.8 secondi (75BPM)
 0.8::second => dur quarter;
// Impostiamo, di conseguenza, il valore della semibreve o intero
 4::quarter => dur whole;
// Impostiamo il valore della minima (1/2)
 whole/2 => dur half;
// Impostiamo il valore della croma (1/8)
 quarter/2 => dur eighth;

Random Music

Vi lascio con un ultimo programma, molto semplice, che genera musica in modo assolutamente casuale. In questa porzione di codice ci sono cose che ancora non abbiamo visto ma i commenti inseriti credo lo rendano piuttosto chiaro:

/* Random Music */
SinOsc sine => dac;
// Loop infinito
 while (true)
 {
 // Frequenza casuale tra 100 e 1000
 Math.random2(100,1000) => sine.freq;
// Durata casuale tra 30 e 1000 ms
 Math.random2f(30,1000) :: ms => now;
 }

Chuck 101 – Lezione 2: Tipi di dati e variabili

Con la prima lezione abbiamo cominciato ad avventurarci nel fantastico mondo di ChucK; ora è arrivato il momento di definire un paio di concetti fondamentali per sviluppare le nostre future applicazioni musicali: tipologie di dati e variabili.

Tipi di dati

La maggior parte dei dati che ci troveremo a gestire all’interno di ChucK sono numeri. Quando si programma si incontrano principalmente due categorie di numeri: integerfloating points. Nel primo gruppo rientrano tutti i numeri senza decimali, nel secondo quelli che invece li hanno.

1 – 45 – 3945 – 20395 sono tutti numeri di tipo integer.

1.2 – 2.3495 – 294056.1 – 394.12 sono, invece, dei float (abbreviazione di floating points).

Esempio 1: Integer

In questo programma in ChucK, opportunamente commentato, vediamo come creare una variabile chiamata «a» a cui assegnamo un valore integer pari a 4. Infine, stampiamo a schermo la nostra variabile:

/*
* Chuck 101 - Lezione 2
* Tipi di dati e variabili
*/
// Esempio Integer
// Definiamo una variabile 'a' come integer;
int a;
// Assegnamo alla nostra variabile un valore numerico
4 => a;
// Scriviamo il valore di a
<<< a >>>;

Se avete fretta c’è un metodo più veloce per assegnare un valore direttamente a una variabile; possiamo sostituire la definizione della variabile e l’assegnazione nel precedente programma con il seguente codice:

/*
* Chuck 101 - Lezione 2
* Tipi di dati e variabili
*/
// Esempio Integer
// Definiamo una variabile 'a' come integer;
int a;
// Assegnamo alla nostra variabile un valore numerico
4 => int a;
// Scriviamo il valore di a
<<< a >>>;

Operazioni matematiche

Ora che abbiamo imparato ad assegnare numeri a delle variabili, possiamo sbizzarrirci con le operazioni matematiche;

Provate a scrivere nel vostro programma:

// Definiamo una variabile 'a' come integer;
4 => int a;
// Moltiplichiamo per 4 la nostra variabile
5*a => a;
// Scriviamo il valore di a
<<< a >>>;

Se tutto è stato scritto correttamente,  nella virtual machine dovreste leggere: 20 : (int)

Anche in questo caso possiamo ricorrere alla seguente scorciatoia per velocizzare la programmazione:

// Definiamo una variabile 'a' come integer;
4 => int a;
// Moltiplichiamo per 4 la nostra variabile
5*=> a;
// Scriviamo il valore di a
<<< a >>>;

Esempio 2: Floating Points

Utilizziamo ora una variabile ti tipo floating points (quindi con dei numeri decimali) all’interno di un programma “musicale”.

/*
* Chuck 101 - Lezione 2
* Tipi di dati e variabili
*/
SinOsc sine => dac;

// Middle C (in Hz)
261.626 => float myFrequency;
// Volume as a variable
0.6 => float myVolume;

// Imposto la frequenza
myFrequency => sine.freq;
// Imposto il volume
myVolume => sine.gain;

// Imposto la durata a 1 secondo.
1::second => now;

Questo piccolo programma riprende in parte quanto fatto la prima lezione ma, anziché assegnare dei valori direttamente alla frequenza e al volume, abbiamo assegnato i valori numeri a delle variabili; così facendo, come vedremo nelle prossime lezioni, potremo modificare i valori con l’avanzare del tempo nel programma.

Per chi se lo stesse chiedendo, il valore 261.626 non è casuale ma è quello riportato in questa tabella e indica, come riportato nel commento, l’esatta frequenza del do centrale nel pianoforte.

Altri tipi di dati

Abbiamo visto variabili di tipo numerico che, come già detto in precedenza, saranno quelle che useremo maggiormente. In ChucK, però, possiamo definire anche altri tipi di variabili: char (un singolo carattere, es: “a”, “b”, “z”, …), string (una stringa di caratteri, es: “hello”, “ciao”, “cartella/fileaudio.wav”), dur (per definire la durata, es: 1::second) e, infine, time (definisce la durata in sample).

Compiti a casa

Nella prossima lezione, analizzeremo nel dettaglio le variabili temporali e la gestione del tempo in ChucK. Nel frattempo, con le nozioni apprese oggi, provate a sperimentare con suoni, variabili e funzioni matematiche per modificare la frequenza assegnata al vostro oscillatore.