1 - Benvenuto :-)

Benvenuto in Sonic Pi. Probabilmente non vedi l’ora di cominciare a fare strani suoni almeno quanto io sono impaziente di mostrarti come si fa. Sarà un viaggio veramente divertente nel quale imparerai tutto su musica, sintesi, programmazione, composizione, performance e altro.

Un momento, non mi sono nemmeno presentato! Sono Sam Aaron - il tipo che ha realizzato Sonic Pi. Mi puoi trovare su Twitter @samaaron e mi farà molto piacere conoscerti. Magari ti interessa sapere qualcosa di più anche delle mie Live Coding Performances dove scrivo codice dal vivo con Sonic PI davanti al pubblico.

Se hai qualche suggerimento o idea per migliorare Sonic PI, mi raccomando, fammela sapere: il tuo feedback è un aiuto importante. Non si può mai sapere, la tua idea potrebbe essere la prossima “big feature”!

Questo tutorial è suddiviso in sezioni raggruppate in categorie. Anche se l’ho pensato per un apprendimento facile e progressivo dall’inizio alla fine, sentiti libero di passare da un argomento all’altro senza seguire necessariamente l’ordine del tutorial. Se pensi che manchi qualcosa, fammelo sapere e io prenderò in considerazione il tuo suggerimento per una prossima versione.

Infine, guardare gli altri che fanno live coding è un ottimo modo per imparare. Sono spesso on line su http://youtube.com/samaaron quindi lasciami un messaggio e fammi tante domande :-)

Ok, possiamo cominciare…


1.1 - Programmare dal vivo

Uno degli aspetti più divertenti di Sonic Pi è che ti permette di scrivere e modificare codice live per fare musica, proprio come se suonassi una chitarra dal vivo. Questo significa che dopo un po’ di pratica puoi salire sul palco ed esibirti con Sonic Pi.

Libera la tua mente

Prima di entrare nel vivo del funzionamento di Sonic Pi, vorrei farti capire meglio cosa vuol dire programmare dal vivo. Per il momento non ti preoccupare se non capisci molto (o anche nulla) di quello che vedremo. Mettiti solo comodo e divertiti…

Un live loop

Allora cominciamo, copia il codice qui di seguito in uno dei buffer che trovi qui sopra:

live_loop :flibble do
  sample :bd_haus, rate: 1
  sleep 0.5
end

Ora premi il tasto Run e sentirai un bel suono di cassa che batte a tempo. Per fermare il suono basta premere sul tasto Stop. Però, per il momento, non premerlo ancora… Segui invece questi passaggi:

Assicurati che il suono della cassa sia ancora attivo Cambia il valore di sleep da 0.5 a qualcosa di più grande, ad esempio: 1. Premi di nuovo il tasto Run Nota come è cambiata la velocità della batteria. Infine, ricorda questo momento: questa è la prima volta che hai fatto live coding con Sonic Pi ed è probabile che non sarà l’ultima…

Ok, fin qui era abbastanza semplice. Adesso aggiungi qualcos’altro al mix. Sopra sample :bd_haus aggiungi l’istruzione sample :ambi_choir, rate: 0.3. Il tuo codice dovrebbe apparire così:

live_loop :flibble do
  sample :ambi_choir, rate: 0.3
  sample :bd_haus, rate: 1
  sleep 1
end

E adesso, sbizzarrisciti. Cambia il parametro rate: - cosa succede se usi valori grandi, o piccoli, o negativi? Guarda cosa succede se cambi il valore di rate: del campione :ambi_choir anche di pochissimo (diciamo 0.29). Cosa succede se scegli un valore molto piccolo per sleep? Prova a farlo così velocemente da provocare un errore, perché il computer non riesce a stargli dietro (se succede, basta scegliere un valore di sleep più grande e premere di nuovo Run).

Prova a inserire all’inizio di una delle istruzioni sample un #:

live_loop :flibble do
  sample :ambi_choir, rate: 0.3
#  sample :bd_haus, rate: 1
  sleep 1
end

Fai caso a come il # dice al computer di ignorare quello che c’è scritto dopo, e di conseguenza non sentiamo più il campione. In Sonic Pi possiamo usare i commenti per togliere o reinserire elementi al mix.

Infine, ecco qualcosa di divertente con cui giocare. Prendi il codice qui sotto e copialo in un buffer vuoto. Poi, non cercare di capire altro, se non che ci sono due loop - due cose che suonano nello stesso tempo. Quindi, fai quello che sai fare meglio: provare e sperimentare. Ecco alcuni suggerimenti:

Prova a cambiare i valori scritti in blu di rate: e ascolta il suono del campione che cambia. Prova a cambiare i tempi di sleep e senti come tutti e due i loop possono girare a differenti velocità. Prova a rimuovere il commento dalla riga con l’istruzione sample (togli il #) e goditi il suono della chitarra al contrario. Prova a cambiare uno qualsiasi dei valori scritti in blu di mix con numeri che vanno da 0 (tutto fuori dal mix) a 1 (tutto nel mix).

Ricordati di premere Run e sentirai il cambiamento non appena il loop viene suonato di nuovo. Se fai qualche errore, non preoccuparti: premi stop, cancella il codice nel buffer, copia di nuovo il codice originale e sei pronto per ricominciare. Sbagliare è il modo più veloce per imparare…

live_loop :guit do
  with_fx :echo, mix: 0.3, phase: 0.25 do
    sample :guit_em9, rate: 0.5
  end
#  sample :guit_em9, rate: -0.5
  sleep 8
end
live_loop :boom do
  with_fx :reverb, room: 1 do
    sample :bd_boom, amp: 10, rate: 1
  end
  sleep 8
end

Suona e fai esperimenti finché non avrai soddisfatto la tua curiosità su come funziona tutto questo e avrai cominciato a chiederti che altro ci puoi fare. A quel punto sarai pronto per proseguire con il tutorial.

Allora, che aspetti?


1.2 - L’interfaccia di Sonic Pi

Sonic Pi ha un’interfaccia molto semplice per programmare la musica. Diamogli un’occhiata.

Sonic Pi Interface

A - Controlli di riproduzione B - Controlli di modifica C - Info e Help D - Editor del codice E - Pannello preferenze F - Visualizzatore Messaggi G - Sistema d’aiuto H - Visualizzatore di segnale I - Cue Viewer

A. Controlli di riproduzione

Questi tasti rosa sono i controlli principali per far partire o fermare i suoni. Il tasto Run esegue il codice che hai scritto nell’editor, Stop ferma tutto il codice in esecuzione, Save per salvare il codice in un file esterno e Record per registrare (in un file WAV) i suoni riprodotti.

B. Controlli di modifica

These orange buttons allow you to manipulate the code editor. The Size + and Size - buttons allow you to make the text bigger and smaller.

C. Info e Help

Questi tasti blu ti danno accesso alle informazioni, all’aiuto e alle opzioni. Il tasto Info apre la finestra delle informazioni che contiene le notizie su Sonic Pi, il team di sviluppo, la storia, i collaboratori e la community. Il tasto Help apre e chiude l’help (G) e il tasto Prefs apre e chiude la finestra delle opzioni che ti permette di modificare alcune impostazioni di base del programma.

D. Editor del codice

Questa è l’area dove scriverai il tuo codice e comporrai/eseguirai la tua musica. È un semplice editor di testo dove puoi scrivere le tue istruzioni, cancellarle, copiarle e incollarle etc. Pensalo come una versione molto elementare di Word o Google Docs. L’editor cambia il colore delle parole sulla base del loro significato nel linguaggio. Questo all’inizio può sembrare strano, ma presto ti accorgerai che è molto utile. Per esempio, qualunque testo colorato di blu è sicuramente un numero.

E. Pannello delle preferenze

Attraverso il tasto prefs nel gruppo di tasti Info e Help, puoi accedere alle opzioni di configurazione di Sonic Pi. Questo tasto ti permette di aprire e chiudere la finestra delle preferenze che possono essere modificate. Per esempio, forzare la modalità mono, invertire i canali stereo, modificare il livello di dettaglio dei messaggi di log e c’è anche un cursore per il livello del suono in uscita e un selettore audio se stai usando un Raspberry Pi.

F. Visualizzatore messaggi

Quando i tuoi programmi girano, le informazioni su cosa stiano facendo vengono visualizzate nella finestra di log. Di default, noterai che c’è un messaggio per ogni suono che generi e che riporta il tempo esatto in cui il suono viene prodotto. Vedrai che questo ti sarà molto utile quando dovrai fare il debug, ovvero individuare gli errori, del tuo codice o capire cosa sta facendo il tuo programma.

G. Sistema di aiuto

Infine, una delle parti più importanti dell’interfaccia di Sonic Pi è la sezione Help che appare in basso nella finestra del programma. Puoi attivarla o disattivarla usando il tasto Help. La sezione Help contiene aiuti e informazioni su tutti gli aspetti di Sonic Pi, compreso questo tutorial, una lista dei sintetizzatori e dei campioni disponibili, esempi, effetti (FX) ed una lista completa di tutte le funzioni e le istruzioni disponibili nel linguaggio di Sonic Pi.

H. Visualizzatore di segnale

Il visualizzatore di segnale ti permette di “guardare” il suono che stai ascoltando. Poi osservare facilmente che l’onda a dente di sega ha davvero la forma di una sega e che il beep è una curva della funzione seno. Puoi inoltre distinguere i suoni forti dai suoni deboli osservando la grandezza delle linee. Ci sono tre sezioni a disposizione: la predefinita è dedicata alla combinazione dei canali destro e sinistro, poi c’è quella che permette di visualizzare i due canali separatamente e infine c’è la sezione che mostra la “figura di Lissajous”. Quest’ultima indica la relazione parametrica fra canale sinistro e canale destro, inoltre ti permette di disegnare delle forme geometriche con il suono (https://en.wikipedia.org/wiki/Lissajous_curve).

I. Cue Viewer

All internal and external events (called cues in Sonic Pi) are automatically logged in the Cue Viewer. For example, if you have a MIDI controller connected and press one of its buttons, you’ll see a new cue event in the Cue Viewer telling you the name of the controller and which button you pressed. Once you’ve mastered the basics of making and producing sounds, you’ll start to want to cue sounds or whole sections of sounds based on events such as these. A cue event is just an indication that something happened. For example, every time a live loop spins round, it sends a cue event out which is logged in the Cue Viewer. Also, external events such as MIDI messages from connected MIDI equipment and OSC messages from other programs or computers are also displayed in the Cue Viewer. It is also possible to directly generate cue events using the cue function. Anything that appears in the Cue Viewer can be used to trigger something happening. This is covered in more detail in Sections 10 to 12 of this tutorial.


1.3 - Imparare suonando

Sonic PI ti incoraggia ad imparare sia l’informatica che la musica suonando e sperimentando. La cosa più importante è che, mentre ti diverti, senza accorgertene impari a programmare, a comporre e a esibirti.

Non esistono errori

Già che ne stiamo parlando, permettimi di darti una dritta che ho imparato in anni di live coding in musica: non esistono errori, ma solo opportunità. È una cosa che ho spesso sentito dire a proposito del jazz, ma funziona altrettanto bene con il live coding. Non importa quanto tu sia esperto - un principiante o un Algoraver navigato: ti capiterà sempre di eseguire del codice dal risultato completamente inaspettato. Potrebbe suonare maledettamente bene, e allora vai tranquillo. Ma potrebbe suonare anche totalmente cacofonico e sballato. Non è importante quello che è venuto fuori, ma quello che ci farai subito dopo. Prendi il suono, manipolalo e modellalo fino a farlo diventare qualcosa di spettacolare. Il pubblico impazzirà.

Comincia dalle cose semplici

Mentre si sta imparando, si è tentati di fare subito cose straordinarie. Metti da parte questo obiettivo e consideralo come qualcosa da raggiungere più in là. Per adesso, pensa piuttosto che la cosa più semplice che potresti scrivere con divertimento e soddisfazione è un piccolo passo verso ciò che hai in mente. Una volta che hai un’idea su quel piccolo passo, prova a realizzarlo, suonalo e vedi quali nuove idee ti suggerisce. Sarai ben presto troppo occupato a divertirti e a fare progressi concreti.

Accertati sempre di condividere il tuo lavoro con gli altri!


2 - Synth (Sintetizzatori)

OK, di introduzione ne abbiamo abbastanza - cominciamo a produrre qualche suono.

In questa parte vedremo le basi dell’utilizzo dei synth. Synth è l’abbreviazione di synthesizer (sintetizzatore), che è una strana parola per indicare un generatore di suoni. Di solito i synth sono abbastanza complicati da usare - specialmente quelli analogici che sono formati da tanti moduli collegati fra di loro da decine di cavi. Sonic Pi, invece, permette gran parte di quella potenzialità, ma in modo semplice e intuitivo.

Non farti ingannare dall’apparente semplicità dell’interfaccia di Sonic Pi. Potrai arrivare a padroneggiare tecniche molto potenti di manipolazione del suono, se non ti mancherà la passione. Reggiti forte alla sedia…


2.1 - I tuoi primi Beep

Dai un’occhiata a questa istruzione:

play 70

È da qui che comincia tutto. Copiala e incollala nella finestra del codice in alto (il grande spazio bianco sotto il tasto Run). Ora, premi Run…

Beep!

Forte, no?. Premilo ancora. E ancora. E ancora…

Wow, pazzesco, sono sicuro che potresti continuare così per tutto il giorno. Ma aspetta, prima di perderti in un flusso infinito di beep, prova a cambiare il numero:

play 75

Senti la differenza? Prova con un numero più piccolo:

play 60

So, lower numbers make lower pitched beeps and higher numbers make higher pitched beeps. Just like on a piano, the keys at the lower part of the piano (the left hand side) play lower notes and the keys on the higher part of the piano (the right hand side) play higher notes.

play 60

Non ti preoccupare se ti sembra che non abbia alcun senso: nemmeno per me lo aveva quando ho cominciato. Tutto quello che ti serve di sapere per ora è che numeri piccoli fanno beep più gravi e numeri grandi fanno beep più acuti.

Accordi

Suonare una nota è divertente, ma suonarne tante contemporaneamente può esserlo anche di più. Prova:

play 72
play 75
play 79

Forte! Quindi, quando scrivi tanti play, suonano tutti contemporaneamente. Prova da solo: quali numeri suonano bene insieme? Quali invece stridono? Sperimenta, esplora e scopri da solo.

Melodia

Quindi, suonare note e accordi è divertente, ma che ne dici di provare con una melodia? Ovvero, come si fa a far suonare una nota dopo l’altra e non tutte insieme? Beh, è facile, basta fare una pausa (sleep) tra le note:

play 72
sleep 1
play 75
sleep 1
play 79

Che bello, un piccolo arpeggio. Ma che significa quell’ 1 in sleep 1? Quel numero indica la durata dello sleep. Vuol dire: “fermati per un beat”, ma per il momento pensiamo che significhi uno stop di un secondo. E se invece volessimo suonare il nostro arpeggio un po’ più velocemente? Basta usare valori più piccoli per l’istruzione sleep. Che ne dici della metà, 0.5?

play 72
sleep 0.5
play 75
sleep 0.5
play 79

Hai notato che suona più veloce? Ora prova, da solo, a cambiare note e tempi.

Una cosa che puoi provare sono i valori intermedi per le note, come play 52.3 oppure play 52.63. Non c’è nessun bisogno, infatti, di limitarsi ai valori interi delle note. Divertiti a provare da solo.

Nomi tradizionali delle note

(N.d.T. in inglese le note si chiamano con le lettere dell’alfabeto e cominciano dal La invece che dal Do. Quindi A = La, B = Si, C = Do, D = Re, E = Mi, F = Fa, G = Sol.) Se già conosci un po’ di notazione musicale (se non la conosci non ti preoccupare, per il momento non è necessaria per divertirsi) potresti voler scrivere una melodia usando i nomi delle note come C e F# invece dei numeri. Sonic Pi ha pensato anche a questo. Puoi fare così:

play :C
sleep 0.5
play :D
sleep 0.5
play :E

Non dimenticare i due punti : prima del nome della nota in modo che diventi rosa. Puoi anche specificare l’ottava indicando un numero dopo il nome della nota:

play :C3
sleep 0.5
play :D3
sleep 0.5
play :E4

Se ti serve una nota col diesis (in inglese sharp), aggiungi una s dopo il nome della nota come in play :Fs3 o se ti serve col bemolle (in inglese flat) aggiungi una b come in play :Eb3.

Ora puoi sbizzarrirti a far suonare note, accordi e melodie.


2.2 - Paramentri dei Synth: Amp e Pan

Oltre a permetterti di controllare quale nota o quale campione suonare, Sonic Pi fornisce un insieme completo di parametri per inventare e controllare il suono. Ne incontreremo molti in questo tutorial e puoi trovare una trattazione completa nell’help. Per il momento, però, ne introdurremo due tra i più utili: ampiezza e bilanciamento (in inglese amplitude e pan). Prima di tutto diamo un’occhiata a cosa sono effettivamente i parametri.

Parametri

Sonic Pi usa il concetto di parametro per i suoi synth. I parametri sono quantità che vengono passati all’istruzione play e che controllano e modificano caratteristiche del suono che ascolti. Ogni synth ha il suo gruppo di parametri per controllare in modo dettagliato il suono generato, ma comunque molti synth hanno in comune alcuni parametri come per esempio amp: e quelli che riguardano l’inviluppo (trattati in un paragrafo successivo).

I parametri hanno due parti, il nome (ovvero il nome del controllo) e il valore (il valore a cui vuoi impostare il controllo). Per esempio, potresti avere un parametro che si chiama cheese: e volerlo impostare al valore 1.

I parametri sono passati alle istruzioni play usando una virgola , seguita dal nome del parametro, per esempio amp: (non dimenticare i due punti :) e quindi da uno spazio e dal valore del parametro. Per esempio:

play 50, cheese: 1

(Nota bene che cheese: non è un parametro valido, è solo per fare un esempio).

Puoi passare più parametri in una volta separandoli con una virgola:

play 50, cheese: 1, beans: 0.5

L’ordine dei parametri non conta, quindi questa istruzione ha lo stesso effetto di quella precedente:

play 50, beans: 0.5, cheese: 1

I parametri che non sono riconosciuti dal synth vengono ignorati (come cheese e beans che sono ovviamente nomi assurdi per dei parametri!)

Se per sbaglio usi lo stesso parametro due volte con diversi valori, l’ultimo vince. Per esempio beans in questa istruzione avrà il valore 2 invece di 0.5:

play 50, beans: 0.5, cheese: 3, eggs: 0.1, beans: 2

Molte cose in Sonic Pi accettano parametri, quindi passa un po’ di tempo a capire come usarli e sarai pronto! Giochiamo un po’ con il nostro primo parametro amp:.

Ampiezza

L’ampiezza è una rappresentazione digitale del volume di un suono. Un’ampiezza elevata produce un suono forte mentre un valore basso di ampiezza produce un suono debole. Come Sonic Pi usa numeri per rappresentare il tempo e le note, allo stesso modo usa numeri per rappresentare anche l’ampiezza. Un’ampiezza di valore 0 equivale al silenzio (non si sentirà nulla) mentre un’ampiezza di valore 1 equivale al volume normale. Puoi anche forzare l’ampiezza a valori più alti (2, 10, 100), ma vedrai che quando l’ampiezza complessiva di tutti i suoni diventa troppo alta, Sonic Pi usa il cosiddetto compressore per riportarla di nuovo a valori tali da non risultare troppo alti per le orecchie. Ciò può rendere il suono confuso e strano. Perciò prova ad usare ampiezze basse, diciamo tra 0 e 0.5, per evitare la compressione.

Amplifichiamo

Per cambiare l’ampiezza di un suono, puoi usare il parametro amp:. Ad esempio, per suonare alla metà del volume, dai un valore di 0.5:

play 60, amp: 0.5

Per suonare ad ampiezza doppia, dai un valore di 2:

play 60, amp: 2

Il parametro amp: modifica soltanto la chiamata a play a cui è associato. Così, ad esempio, la prima chiamata a play è a metà volume, mentre la seconda è di nuovo sul valore di default:

play 60, amp: 0.5
sleep 0.5
play 65

Naturalmente puoi usare differenti valori per amp: per ogni play:

play 50, amp: 0.1
sleep 0.25
play 55, amp: 0.2
sleep 0.25
play 57, amp: 0.4
sleep 0.25
play 62, amp: 1

Bilanciamento

Un altro parametro divertente è pan:, che controlla la collocazione del suono (panning) sul fronte stereofonico. Bilanciare il suono a sinistra significa sentirlo solo dalla cassa di sinistra mentre, spostarlo a destra significa sentirlo dalla cassa di destra. In Sonic Pi usiamo un -1 per posizionare il suono tutto a sinistra, 0 per posizionare il suono al centro e 1 per posizionare il suono tutto a destra. Ovviamente siamo liberi di usare qualsiasi parametro tra -1 e 1 per controllare l’esatto posizionamento del nostro suono.

Facciamo suonare un beep dall’altoparlante a sinistra:

play 60, pan: -1

Ora, dall’altoparlante a destra:

play 60, pan: 1

Infine, facciamolo suonare al centro (che è la posizione di default):

play 60, pan: 0

E adesso divertiti a cambiare le ampiezze e il panning dei tuoi suoni!


2.3 - Muoversi fra i Synth

Finora ci siamo divertiti un sacco con i beep. Ma probabilmente questi semplici beep staranno cominciando ad annoiarti. È tutto qui quello che Sonic Pi ha da offrire? Ci sarà qualcosa di più nel live coding che suonare dei beep! Certo che c’è, e in questa sezione esploriamo la vasta gamma di suoni che offre Sonic Pi.

Synth (Sintetizzatori)

Sonic Pi offre una ampia gamma di strumenti chiamati synth, forma abbreviata per sintetizzatori. Mentre i sample contengono suoni pre-registrati, i synth sono in grado di generare nuovi suoni in base a come li controlli (cosa che esploreremo più in là nel tutorial). I synth di Sonic Pi sono molto potenti ed espressivi e ti divertirai molto nell’esplorarne le possibilità e nel suonarli. Per prima cosa, impariamo a selezionare il synth da suonare.

Onde a dente di sega e prophets

Un suono divertente è il dente di sega. Proviamolo:

use_synth :saw
play 38
sleep 0.25
play 50
sleep 0.25
play 62
sleep 0.25

Adesso proviamo un altro suono - il prophet:

use_synth :prophet
play 38
sleep 0.25
play 50
sleep 0.25
play 62
sleep 0.25

E se combinassimo insieme due suoni? Prima uno, poi l’altro:

use_synth :saw
play 38
sleep 0.25
play 50
sleep 0.25
use_synth :prophet
play 57
sleep 0.25

Now multiple sounds at the same time (by not sleeping between successive calls to play):

use_synth :tb303
play 38
sleep 0.25
use_synth :dsaw
play 50
sleep 0.25
use_synth :prophet
play 57
sleep 0.25

Nota che il comando use_synth influenza soltanto le chiamate seguenti a play. Pensalo come un grande switch - le nuove chiamate a play useranno qualsiasi sintetizzatore sia in uso in quel momento. Puoi regolare lo switch su un nuovo synth con l’istruzione use_synth.

Alla scoperta dei Synth

Per vedere quali sintetizzatori Sonic Pi mette a tua disposizione, dai un’occhiata all’opzione Synths (prima di Fx) nel menu verticale in basso a sinistra. Ce ne sono più di 20 tra cui scegliere. Ecco qui sotto soltanto alcuni dei miei preferiti:

:prophet :dsaw :fm :tb303 :pulse

Ora divertiti a cambiare i synth mentre fai la tua musica. Divertiti a combinare i synth per fare nuovi suoni e ad usare synth differenti in diverse sezioni della tua musica.


2.4 - Durate e inviluppi

Nelle sezioni precedenti, abbiamo visto come usare il comando sleep per controllare l’attacco della nota, ma non siamo ancora in grado di controllare la durata dei suoni.

Per dotarci di uno strumento semplice ma potente per controllare le durate dei suoni, Sonic Pi implementa il concetto di inviluppo ADSR (ci occuperemo più oltre in questa stessa sezione di cosa voglia dire ADSR). Un inviluppo di ampiezza permette di gestire due utili aspetti del controllo:

controllo della durata di un suono controllo dell’ampiezza di un suono

Durata

La durata è il tempo che un suono… dura! Una durata più lunga significa che sentirai il suono per un tempo più lungo. Tutti i suoni in Sonic Pi hanno un inviluppo di ampiezza controllabile, e la durata di tale inviluppo corrisponde alla durata del suono. Quindi, controllando l’inviluppo, controlli allo stesso tempo la durata.

Ampiezza

L’inviluppo ADSR non controlla soltanto la durata, ma fornisce anche un controllo accurato dell’ampiezza del suono. Tutti i suoni udibili iniziano dal silenzio e finiscono nel silenzio, e contengono una parte non-silenziosa nel mezzo. Gli inviluppi ti permettono di variare e mantenere l’ampiezza della parte non-silenziosa del suono. È come dare a qualcuno istruzioni su come e quanto alzare e abbassare il volume dell’amplificatore della chitarra. Per esempio, potresti chiedere a questa persona di iniziare dal silenzio, alzare il volume lentamente fino al massimo, mantenerlo per un po’ e riabbassarlo di colpo. Sonic Pi ti permette di controllare con precisione questo tipo di comportamento mediante gli inviluppi.

Tanto per riassumere: come abbiamo visto prima, una ampiezza di 0 equivale a silenzio e un’ampiezza 1 è il volume normale.

Ora, diamo un’occhiata alle parti da cui l’inviluppo è composto.

Fase di rilascio (Release)

L’unica parte dell’inviluppo che viene usata di default è il rilascio (release). Si tratta del tempo che il suono di un synth impiega a sfumare. Tutti i synth hanno un tempo di rilascio impostato a 1, il che vuol dire che, di default, hanno la durata di 1 beat (che a sua volta, al tempo di default di 60BPM, equivale a 1 secondo):

play 70

La nota resterà udibile per 1 secondo. Prova a verificare tu stesso. Questa era la forma breve in luogo di quella più lunga ed esplicita:

play 70, release: 1

Nota come il suono abbia esattamente la stessa durata di prima (il suono dura un secondo). Ma ora è molto facile cambiare la durata modificando il valore dell’opzione release::

play 60, release: 2

Possiamo anche far suonare il synth per una durata molto breve usando un valore molto piccolo del tempo di rilascio:

play 60, release: 0.2

La durata del rilascio di un suono è chiamata fase di rilascio e, di default, è una transizione lineare (cioè segue una linea retta), Il seguente diagramma illustra questa transizione:

release envelope

La linea verticale sulla sinistra del diagramma indica che il suono comincia ad ampiezza 0, ma sale ad ampiezza massima immediatamente (questa è la fase di attacco, di cui ci occuperemo dopo). Raggiunta l’ampiezza massima, scende con una linea diritta fino a zero, e per fare questo impiega esattamente il tempo specificato da release:. Valori di release più lunghi producono dissolvenze più lente.

Ora poi cambiare la durata dei suoni cambiando il tempo di rilascio. Divertiti ad aggiungere i tempi di rilascio alle note della tua musica.

Fase d’attacco

Di default, la fase d’attacco è 0 per tutti i synth, il che significa che questi salgono da ampiezza 0 a 1 immediatamente. Ciò conferisce ai synth un timbro percussivo. Tuttavia, potresti volere che il suono raggiunga l’ampiezza 1 più lentamente (fade in). Puoi ottenere questo risultato con l’opzione attack::

play 60, attack: 2
sleep 3
play 65, attack: 0.5

Puoi usare opzioni multiple contemporaneamente. Per esempio, per un attacco corto e un rilascio lungo, prova così:

play 60, attack: 0.7, release: 4

Un inviluppo con attacco corto e rilascio lungo è illustrato nel diagramma seguente:

attack release envelope

È ovvio che puoi fare anche l’inverso. Prova un attacco lungo e un rilascio corto:

play 60, attack: 4, release: 0.7

long attack short release envelope

Infine, puoi anche impostare un tempo corto sia per l’attacco che per il rilascio, per avere suoni più brevi.

play 60, attack: 0.5, release: 0.5

short attack short release envelope

Fase di sostegno (Sustain)

Oltre ai tempi di attacco e rilascio, puoi specificare anche un tempo di sostegno (sustain) per controllare la fase di sostegno. Essa corrisponde al tempo in cui il suono è mantenuto ad ampiezza fissa dopo l’attacco e prima del rilascio.

play 60, attack: 0.3, sustain: 1, release: 1

ASR envelope

Il tempo di sostegno è utile per suoni a cui vuoi dare maggior presenza nel mix prima di inserire una fase, opzionale, di rilascio. Naturalmente, è del tutto valido anche impostare sia l’attacco che il rilascio a 0 per non avere alcun tipo di dissolvenza né in entrata né in uscita. Bada però che un tempo di rilascio uguale a 0 genera dei click, ed è meglio usare valori molto piccoli come 0.2.

Fase di decadimento (Decay)

Per un ulteriore livello di controllo, puoi specificare anche un tempo di decadimento. Si tratta di una fase dell’inviluppo che si trova tra attacco e sostegno e specifica il tempo in cui l’ampiezza scende da attack_level: (livello d’attacco) a decay_level: (livello di decadimento). Di default, l’opzione decay: ha valore 0 e sia il livello di attacco che il livello di sostegno sono impostati su 1, e ciò significa che dovrai impostarne il valore in modo esplicito se vuoi che il tempo di decadimento sortisca qualche effetto:

play 60, attack: 0.1, attack_level: 1, decay: 0.2, sustain_level: 0.4, sustain: 1, release: 0.5

ADSR envelope

Livello di decadimento

Un’altra possibilità è impostare esplicitamente i valori di decay_level: e sustain_level: (anche se di default sono uguali) per avere pieno controllo sull’inviluppo. Ciò consente di creare inviluppi nel modo seguente:

play 60, attack: 0.1, attack_level: 1, decay: 0.2, decay_level: 0.3, sustain: 1, sustain_level: 0.4, release: 0.5

ASR envelope

È possibile anche impostare un decay_level: più alto del sustain_level::

play 60, attack: 0.1, attack_level: 0.1, decay: 0.2, decay_level: 1, sustain: 0.5, sustain_level: 0.8, release: 1.5

ASR envelope

Inviluppi ADSR

Riassumendo, gli inviluppi di Sonic Pi hanno le seguenti fasi:

tempo di attacco: per transitare da ampiezza 0 a attack_level, tempo di decadimento: per transitare da attack_level a decay_level, tempo di sostegno: per transitare da decay_level a sustain_level, tempo di rilascio: per transitare da sustain_level a 0

È importante sottolineare che la durata di un suono è pari alla somma dei tempi di ciascuna di queste quattro fasi. Quindi, il suono seguente avrà una durata pari a 0.5 + 1 + 2 + 0.5, ovvero 4 beat:

play 60, attack: 0.5, attack_level: 1, decay: 1, sustain_level: 0.4, sustain: 2, release: 0.5

E adesso datti da fare ad aggiungere gli inviluppi ai tuoi suoni…


3 - Campioni (Samples)

Un altro modo molto interessante per creare musica è quello di usare suoni pre-registrati. Nella grande tradizione hip-hop li chiamiamo campioni (in inglese, samples). Quindi, se ti armi di microfono e vai in giro a registrare, per esempio, il suono leggero della pioggia su una tela, hai appena creato un campione.

Con Sonic Pi puoi fare un sacco di cose divertenti coi campioni: ci sono più di 90 campioni di pubblico dominio, pronti per i tuoi mix, ma il programma ti permette anche di suonare e trasformare quelli creati da te. Vediamo subito come…


3.1 - Suonare i campioni

Fare i beep è soltanto l’inizio. Una cosa molto divertente è suonare campioni pre-registrati. Prova questo:

sample :ambi_lunar_land

In Sonic Pi troverai molti campioni precaricati coi quali lavorare. Puoi usarli nello stesso modo in cui usi il comando play. Per suonare insieme note e campioni ti basta scrivere le istruzioni una dopo l’altra:

play 36
play 48
sample :ambi_lunar_land
sample :ambi_drone

Se vuoi distribuirli nel tempo, usa l’istruzione sleep:

sample :ambi_lunar_land
sleep 1
play 48
sleep 0.5
play 36
sample :ambi_drone
sleep 1
play 36

Forse avrai notato come Sonic Pi non aspetta la fine di un suono per farne partire un altro? L’istruzione sleep determina solo la separazione degli attacchi dei suoni. Questo ti permette di sovrapporre facilmente i suoni creando interessanti effetti d’insieme. Più avanti nel tutorial vedremo come controllare la durata dei suoni con gli inviluppi.

Scopriamo i campioni

Ci sono due modi per esplorare la varietà di campioni forniti da Sonic Pi. Primo, puoi usare l’help del programma. Fai click su Samples nel menu verticale in basso a sinistra, scegli la categoria e lì vedrai la lista dei suoni disponibili.

Altrimenti puoi usare il sistema di autocompletamento. Prova a scrivere la prima parte del nome di un gruppo di campioni, come: sample: ambi_ e vedrai che apparirà un menu a tendina con i nomi dei campioni tra i quali potrai scegliere. Prova con questi prefissi di categoria:

:ambi_ :bass_ :elec_ :perc_ :guit_ :drum_ :misc_ :bd_

Ora puoi cominciare a mixare campioni per realizzare le tue composizioni!


3.2 - I parametri dei campioni: Amp e Pan

Come abbiamo visto con i sintetizzatori, possiamo facilmente controllare i nostri suoni con i parametri. I campioni supportano esattamente lo stesso meccanismo di parametrizzazione. Torniamo dai nostri amici amp: e pan:.

Regolare l’ampiezza dei campioni

Puoi cambiare l’ampiezza dei campioni con lo stesso sistema che hai usato per i synth:

sample :ambi_lunar_land, amp: 0.5

Il panning dei campioni

Sui campioni possiamo usare anche il parametro pan:. Per esempio, ecco come faremmo per suonare un loop di batteria due volte passando dall’orecchio sinistro al destro:

sample :loop_amen, pan: -1
sleep 0.877
sample :loop_amen, pan: 1

Osserva che 0.877 è metà della durata in secondi del campione :loop_amen.

Ricorda infine che, se imposti alcuni parametri di default dei synth con use_synth_defaults (di cui parleremo più in là), questi saranno ignorati dall’istruzione sample.


3.3 - Stretching dei campioni

Finora abbiamo imparato a suonare una varietà di synth e campioni per fare un po’ di musica. È tempo di imparare a modificare sia i synth che i campioni per rendere la musica ancora più originale e interessante. Prima di tutto, esploriamo la capacità di Sonic Pi di stirare (in inglese, stretch) e schiacciare i suoni.

Rappresentazione dei campioni

I campioni sono suoni pre-registrati immagazzinati come dati numerici che rappresentano come muovere il cono dell’altoparlante per riprodurre il suono. Il cono dell’altoparlante può muoversi in dentro e in fuori, quindi i numeri devono rappresentare lo stato (cioè quanto in dentro o quanto in fuori) in cui si deve trovare il cono dell’altoparlante in ogni istante. Per riprodurre fedelmente un suono registrato, un campione ha bisogno tipicamente di alcune migliaia di numeri al secondo! Sonic Pi prende questa lista di numeri e li riproduce alla velocità opportuna per creare il movimento in dentro e in fuori della membrana degli altoparlanti del computer, esattamente nel modo richiesto per riprodurre quel dato suono. Ma è divertente anche cambiare la velocità con cui i numeri sono inviati agli altoparlanti, in modo da cambiare anche il suono.

Cambiare la velocità

Proviamo a suonare uno dei nostri suoni ambient: :ambi_choir. Per suonarlo alla velocità di default, puoi passare un argomento rate: all’istruzione sample::

sample :ambi_choir, rate: 1

Questa istruzione fa suonare il campione a velocità normale (1), e per il momento non succede niente di speciale. Ma siamo liberi di cambiare quel numero in qualcos’altro. Proviamo con 0.5::

sample :ambi_choir, rate: 0.5

Forte! Che cosa sta succedendo? Essenzialmente due cose. Primo, il campione ci mette il doppio a suonare; secondo, il suono è un’ottava sotto. Esploriamo la cosa nel dettaglio.

Stretchiamo

Un campione divertente da stirare e comprimere è il loop di batteria Amen Break. A velocità normale, potremmo immaginare di buttarlo dentro una traccia drum’n bass:

sample :loop_amen

Ma, cambiando la velocità, ecco che possiamo anche cambiare genere. Proviamo a mezza velocità per un hip-hop vintage:

sample :loop_amen, rate: 0.5

Se aumentiamo la velocità, entriamo nel territorio del jungle:

sample :loop_amen, rate: 1.5

Adesso, come ultimo effetto a sorpresa, vediamo che succede se usiamo una velocità negativa:

sample :loop_amen, rate: -1

Wow! Suona al contrario! Proviamo a suonare molti campioni diversi a velocità diverse. Provatene di molto veloci o di lentissime. Guarda che suoni interessanti puoi creare.

Una semplice spiegazione della velocità di lettura del campione

Un modo utile di pensare i campioni è pensarli come molle. La velocità di lettura corrisponde a comprimere e distendere la molla. Se suoni con una velocità 2, stai comprimento la molla a metà della sua lunghezza normale, quindi il campione dura circa metà del tempo, essendo più corto. Se invece suoni il campione a metà velocità, stai distendendo la molla fino a raddoppiarne la lunghezza; di conseguenza il campione dura due volte il tempo normale, essendo più lungo. Più comprimi (velocità maggiori), più corto diventa il suono; più distendi (velocità più basse) più il suono diventa lungo.

Comprimere la molla ne aumenta la densità (numero di giri della molla per centimetro) analogamente al campione che suona più acuto. Allungare la molla fa diminuire la densità, analogamente al campione che suona più grave.

La matematica della velocità di lettura del campione

(Questa parte è per quelli che sono interessati ai dettagli. Sentitevi liberi di saltarla…)

Come abbiamo visto, un campione è rappresentato da una lunga lista di numeri che rappresentano come la membrana dell’altoparlante deve muoversi nel tempo. Possiamo usare questa lista di numeri per tracciare un grafico simile a questo:

sample graph

Potreste aver già visto immagini come questa prima d’ora. Si tratta della forma d’onda del campione. È semplicemente un grafico dei numeri. Tipicamente, una forma d’onda come questa avrà 44100 punti per ogni secondo (ciò è una conseguenza del teorema del campionamento di Nyquist-Shannon). Così, se il campione dura 2 secondi, la forma d’onda sarà rappresentata da 88200 numeri che vengono inviati all’altoparlante, opportunamente convertiti in segnale elettrico, alla velocità di 44100 numeri al secondo. Potremmo naturalmente farlo a frequenza doppia (88200 numeri al secondo), e ci vorrebbe solo un secondo per suonarli tutti. Potremmo anche dimezzare la frequenza a 22050 numeri al secondo, e in quel caso ci vorrebbero 4 secondi per suonare tutta la lista di numeri.

La durata di un campione dipende dalla velocità di lettura del dato digitale:

Raddoppiare la velocità dimezza la durata, Dimezzare la velocità raddoppia la durata, Usare una velocità di lettura di un quarto quadruplica la durata, Usare una velocità di 1/10 rende la durata 10 volte più lunga.

Possiamo rappresentare questo concetto con la seguente formula:

nuova_durata_campione = (1 / velocità) * durata_del_campione 

Cambiare la velocità di lettura influisce anche sul pitch del campione. La frequenza, o pitch di una forma d’onda, è determinata da quanto velocemente essa oscilla. Il nostro cervello interpreta un’oscillazione veloce come note acute e un’oscillazione lenta come note gravi. Ecco perché a volte puoi perfino veder muovere il cono di un grosso altoparlante che emette frequenze molto basse: in effetti, sta effettuando il suo movimento in dentro e in fuori a una velocità molto più bassa di quella di un altoparlante che produce note acute.

Se prendi una forma d’onda e la comprimi, quella oscillerà un numero maggiore di volte al secondo. Ciò renderà il suono più acuto. Comprendiamo allora che raddoppiare il numero di oscillazioni raddoppia la frequenza. Così, suonare il tuo campione a velocità doppia raddoppia la frequenza che ascolti. E dimezzare la velocità dimezza la frequenza. Diverse variazioni di velocità influiranno sulla frequenza in proporzione.


3.4 - Inviluppo dei campioni

È possibile anche modificare la durata e l’ampiezza di un campione adoperando un inviluppo ADSR. Questo funziona però in modo lievemente differente dall’ADSR disponibile nei synth. Gli inviluppi dei campioni ti permettono soltanto di ridurre l’ampiezza e la durata di un campione, ma mai di aumentarle. Il campione si fermerà o quando sarà stato suonato tutto oppure quando sarà completato l’inviluppo, quale delle due cose accada per prima. Quindi, anche se usi un tempo di rilascio (release:) molto lungo, non per questo aumenterai la durata del campione.

Inviluppo del campione Amen

Torniamo al nostro amico fidato, il loop di batteria Amen:

sample :loop_amen

Senza parametri, ascoltiamo il campione intero ad ampiezza piena. Se vogliamo creare un fade-in (dissolvenza in entrata) di 1 secondo, possiamo usare il parametro attack: (tempo di attacco):

sample :loop_amen, attack: 1

Per un fade-in più corto, impostiamo un tempo di attacco più corto:

sample :loop_amen, attack: 0.3

Auto sustain

La fase dell’inviluppo in cui il comportamento dell’ADSR differisce, per i campioni, da quello standard dei synth, è il tempo di sustain: (sostegno). Negli inviluppi standard dei synth, esso è impostato di default su 0 a meno che non venga impostato manualmente su un valore diverso. Con i campioni, il sustain si imposta su un valore automagico, cioè il tempo necessario ad eseguire il resto del campione. Ecco perché sentiamo l’intero campione quando non impostiamo alcun valore. Se attacco, decadimento, sostegno e rilascio fossero tutti impostati su 0, non sentiremmo un bel niente. Sonic Pi calcola perciò la lunghezza del campione, ne sottrae eventuali tempi di attacco, decadimento e rilascio, e usa il risultato come tempo di sostegno. Se attacco, decadimento e rilascio sommati durano più della durata effettiva del campione, il sustain è lasciato, semplicemente, a 0.

Fade out (dissolvenza in uscita)

Per esaminare questo aspetto, consideriamo il nostro loop Amen più in dettaglio. Se chiediamo a Sonic Pi quanto dura il campione:

print sample_duration :loop_amen

lui stamperà 1.753310657596372, che è la lunghezza del campione in secondi. Per comodità, arrotondiamolo a 1.75. Adesso, se impostiamo il rilascio a 0.75, ecco cosa accade:

sample :loop_amen, release: 0.75

Suonerà il primo secondo del campione ad ampiezza piena prima di dissolvere in un tempo di 0.75 secondi. Ecco l’autosustain in azione. Di default, il rilascio funziona sempre contando a ritroso dalla fine del campione. Se il nostro campione fosse di 10.75 secondi, suonerebbe i primi 10 secondi ad ampiezza piena prima di dissolvere in 0.75 secondi.

Ricorda: di default il tempo di rilascio va contato dalla fine del campione.

Fade in e fade out (dissolvenza in entrata e in uscita)

Possiamo usare insieme sia attack: che release: con l’autosustain per avere sia il fade in che il fade out sulla durata del campione:

sample :loop_amen, attack: 0.75, release: 0.75

Dal momento che la durata completa del campione è 1.75 secondi e i nostri tempi di attacco e rilascio durano complessivamente 1.5 secondi, il sustain è impostato automaticamente a 0.25 secondi. Ciò permette di applicare le dissolvenze al campione con grande facilità.

Sustain esplicito

Possiamo benissimo tornare al comportamento normale dell’ADSR dei synth impostando sustain: manualmente su un valore, ad esempio 0:

sample :loop_amen, sustain: 0, release: 0.75

Adesso il nostro campione suona per soli 0.75 secondi totali. Con il valore di default 0 per attack: e decay:, il campione va immediatamente alla massima ampiezza, tiene il suono per…0 secondi e poi se ne va ad ampiezza 0 con un tempo di rilascio di 0.75 secondi.

Piatti… percussivi

Possiamo servirci di questo comportamento come effetto per trasformare campioni lunghi in versioni corte e più percussive dello stesso campione. Consideriamo il campione :drum_cymbal_open:

sample :drum_cymbal_open

Puoi sentire il suono del piatto riusuonare per un certo tempo. Tuttavia, possiamo usare il nostro inviluppo per rendere il suono più percussivo:

sample :drum_cymbal_open, attack: 0.01, sustain: 0, release: 0.1

Puoi emulare il colpo di piatto e il successivo smorzamento aumentando il tempo di sostegno:

sample :drum_cymbal_open, attack: 0.01, sustain: 0.3, release: 0.1

E adesso divertiti ad applicare gli inviluppi ai campioni. Prova a cambiare anche la velocità di lettura per risultati davvero interessanti.


3.5 - Esecuzione parziale dei campioni

Con questa sezione si conclude la nostra esplorazione su come Sonic Pi gestisce i campioni audio. Facciamo un breve riassunto. Finora abbiamo visto come avviare l’esecuzione di un campione:

sample :loop_amen

Quindi abbiamo visto come cambiare la velocità di lettura dei campioni in modo da farli suonare a velocità dimezzata:

sample :loop_amen, rate: 0.5

Abbiamo visto come inserire un fade-in all’inizio del campione (ora facciamolo a velocità dimezzata):

sample :loop_amen, rate: 0.5, attack: 1

Abbiamo visto anche come dare al campione un attacco percussivo dando un valore di sustain: esplicito (zero) e impostando attacco e rilascio su valori molto corti:

sample :loop_amen, rate: 2, attack: 0.01, sustain: 0, release: 0.35

Ma non sarebbe bello se non dovessimo suonare il campione sempre dall’inizio? E non sarebbe altrettanto bello non doverlo suonare sempre fino alla fine?

Scegliere il punto d’inizio

È possibile scegliere un punto d’inizio a piacere nell’esecuzione del campione come valore associato al parametro start: compreso tra 0 e 1, dove 0 corrisponde all’inizio del campione, 1 alla fine e 0.5 esattamente a metà. Proviamo a suonare soltanto la seconda metà del nostro solito loop di batteria:

sample :loop_amen, start: 0.5

Ed ecco l’ultimo quarto soltanto:

sample :loop_amen, start: 0.75

Scegliere il punto finale

In modo simile è possibile scegliere a piacere un punto finale all’interno del campione impostando un valore tra 0 e 1 per il parametro finish:. Eseguiamo il loop di batteria fino a metà campione:

sample :loop_amen, finish: 0.5

Specificare un punto d’inizio e un punto finale

È possibile, naturalmente, combinare queste due istruzioni per eseguire a piacere un frammento del file audio. Ecco come eseguire una piccola porzione al centro del file:

sample :loop_amen, start: 0.4, finish: 0.6

Ma cosa succede se scegliamo un punto d’inizio collocato dopo il punto finale?

sample :loop_amen, start: 0.6, finish: 0.4

Forte! Suona all’indietro!

Combinare velocità di lettura ed esecuzione parziale del campione

Possiamo combinare questa nuova possibilità di suonare frammenti a scelta di un file audio con la nostra vecchia conoscenza rate:, la velocità di lettura. Possiamo ad esempio eseguire un frammento brevissimo del loop di batteria ad una velocità molto bassa:

sample :loop_amen, start: 0.5, finish: 0.7, rate: 0.2

Combinare inviluppi ed esecuzione parziale del campione

Possiamo infine combinare tutto questo con gli inviluppi ADSR per ottenere risultati interessanti:

sample :loop_amen, start: 0.5, finish: 0.8, rate: -0.2, attack: 0.3, release: 1

E ora sbizzarriamoci a creare mix di campioni manipolati in tutti questi fantastici modi…


3.6 - Campioni esterni

Con i campioni compresi in Sonic Pi puoi cominciare a lavorare subito. Tuttavia, arriverai a voler sperimentare inserendo altri suoni registrati nella tua musica. Prima però discutiamo brevemente sulla portabilità del tuo pezzo.

Portabilità

Quando componi un pezzo soltanto con i synth e i campioni compresi in Sonic Pi, tutto ciò di cui hai bisogno per riprodurre fedelmente la tua musica è il codice. Pensaci un attimo - è straordinario! Un semplice frammento di testo che puoi inviare per email o depositare in un [Gist] (https://gist.github.com) è tutto quello che ti serve per riprodurre i tuoi suoni. Ciò rende davvero facile condividerli con i tuoi amici, perché tutto quello di cui anche loro hanno bisogno è il codice.

Tuttavia, se cominci ad usare campioni tuoi, perdi la portabilità. Questo perché, per riprodurre la tua musica, le altre persona non hanno bisogno soltanto del codice, ma anche dei campioni. Ciò limita la possibilità per gli altri di manipolare, creare mix e sperimentare con il tuo lavoro. Naturalmente questo non deve impedirti di usare suoni tuoi: è solo un fatto da tenere in considerazione.

Campioni locali

Ma insomma come si fa a suonare un qualsiasi file WAV o AIFF residente nel tuo computer? Devi soltanto passare il percorso di quel file all’istruzione sample:

# Raspberry Pi, Mac, Linux
sample "/Users/sam/Desktop/my-sound.wav"
# Windows
sample "C:/Users/sam/Desktop/my-sound.wav"

In questo modo Sonic Pi carica automaticamente il campione e lo suona. A quel punto puoi passare tutti i parametri standard che hai usato finora con sample:

# Raspberry Pi, Mac, Linux
sample "/Users/sam/Desktop/my-sound.wav", rate: 0.5, amp: 0.3
# Windows
sample "C:/Users/sam/Desktop/my-sound.wav", rate: 0.5, amp: 0.3

3.7 - Pacchetti di sample

Nota: questa sezione del tutorial copre argomenti avanzati e spiega come lavorare con directory contenenti molti sample. Questo, ad esempio, può accadere se hai scaricato o comprato dei sample pack e vuoi utilizzarli con Sonic Pi.

Sentiti libero di saltare questa sezione se i campioni già presenti in Sonic Pi ti sono sufficienti.

Quando lavori con cartelle piene di file esterni, può essere scomodo digitare l’intero percorso ogni volta che vuoi lanciare un singolo campione.

Per esempio, facciamo finta che tu abbia questa cartella sul tuo computer:

/path/to/my/samples/

Quando guardiamo all’interno di quella cartella, troviamo i seguenti campioni:

100_A#_melody1.wav 100_A#_melody2.wav 100_A#_melody3.wav 120_A#_melody4.wav 120_Bb_guit1.wav 120_Bb_piano1.wav

Di solito, per suonare i campioni di pianoforte dovremmo usare il percorso completo:

sample "/path/to/my/samples/120_Bb_piano1.wav"

Se volessimo usare anche i campioni di chitarra, anche in questo caso dovremmo usare il percorso completo:

sample "/path/to/my/samples/120_Bb_guit.wav"

Purtroppo, per caricare questi campioni è necessario conoscere i nomi dei campioni all’interno della nostra cartella. E se volessimo ascoltare velocemente ciascun sample a turno?

Indicizzare i pacchetti di campioni

Se vogliamo suonare il primo campione in una cartella, dobbiamo semplicemente passare il nome della cartella al comando samplee l’indice 0 in questo modo:

sample "/path/to/my/samples/", 0

Se vogliamo, possiamo anche creare una scorciatoia per la nostra cartella utilizzando una variabile:

samps = "/path/to/my/samples/"
sample samps, 0

Ora, se vogliamo suonare il secondo sample nella directory, dobbiamo aggiungere 1 al nostro indice:

samps = "/path/to/my/samples/"
sample samps, 1

Puoi notare come non sia più necessario conoscere i nomi dei campioni nella cartella, dobbiamo solo conoscere la posizione della cartella stessa (o avere una scorciatoia). Se proviamo a utilizzare un indice maggiore del numero dei campioni, ripartirà semplicemente da capo come nei Rings. Per cui, indipendentemente dal numero usato, abbiamo la sicurezza che verrà utilizzato un campione in quella cartella.

Filtrare i pacchetti di campioni

Di solito è sufficiente indicizzare, ma qualche volta abbiamo bisogno di maggiore potenza per organizzare i nostri campioni. Per fortuna molti pacchetti di campioni aggiungono informazioni nei nomi dei file. Diamo ancora un’occhiata ai campioni nella nostra cartella:

100_A#_melody1.wav 100_A#_melody2.wav 100_A#_melody3.wav 120_A#_melody4.wav 120_Bb_guit1.wav 120_Bb_piano1.wav

Puoi notare come i nomi dei file hanno molte informazioni. Per iniziare abbiamo il BPM del sample (beat per minuto) all’inizio del nome. PEr cui se il campione del pianoforte è a 120BPM mentre le nostre tre melodie sono a 100BPM. In aggiunta, il nome dei campioni contiene anche la tonalità: il campione di chitarra è in Bb (Si bemolle) e le melodie in A# (La diesis). Questa informazione è molto utile per mixare questi sample con il nostro codice. Per esempio, sappiamo che possiamo suonare il campione del piano se il nostro codice è a 120BPM e in tonalità di Bb.

È possibile usare questa convenzione sui nomi dei file del nostro set di campioni nel codice per aiutarci a filtrare quelli che vogliamo. Per esempio, se stiamo lavorando a 120BPM, possiamo visualizzare tutti i campioni che contengono la stringa "120" come segue:

samps = "/path/to/my/samples/"
sample samps, "120"

Questo farà suonare il primo risultato. Se volessimo il secondo, possiamo usare l’indice:

samps = "/path/to/my/samples/"
sample samps, "120", 1

Possiamo anche usare più filtri contemporaneamente. Per esempio, se vogliamo utilizzare i campioni il cui nome contenga sia “120” che “A#” possiamo farlo usando questo codice:

samps = "/path/to/my/samples/"
sample samps, "120", "A#"

Infine, possiamo sentirci liberi di usare i parametri di sample che abbiamo già visto:

samps = "/path/to/my/samples/"
sample samps, "120", "Bb", 1, lpf: 70, amp: 2

Fonti

Il sistema di filtro dei campioni capisce due tipi di informazioni: la fonte e i filtri. Le fonti sono informazioni usate per creare la lista dei potenziali candidati. Una fonte può avere due forme:

“/path/to/samples” - una stringa che rappresenta un percorso valido a una cartella “/path/to/samples/foo.wav” - una stringa che rappresenta un percorso valido per un campione

La funzione sample raccoglierà per prima cosa tutte le fondi e le userà per creare una lunga lista di possibili candidati. Questa lista viene costruita aggiungendo tutti i percorsi e tutti i file con estensione .flac, .aif, .aiff, .wav, .wave contenuti all’interno della cartella.

Per esempio, diamo un’occhiata a questo codice:

samps = "/path/to/my/samples/"
samps2 = "/path/to/my/samples2/"
path = "/path/to/my/samples3/foo.wav"
sample samps, samps2, path, 0

In questo caso stiamo combinando il contenuto dei campioni all’interno di due cartelle e aggiungendo un campione specifico. Se "/path/to/my/samples/" contiene 3 campioni e "/path/to/my/samples2/" ne contiene 12, abbiamo 16 potenziali campioni da indicizzare e filtrare (3 + 12 + 1).

Per impostazione predefinita, sono inclusi nella lista dei candidati solo i campioni contenuti in una cartella. E’ possibile talvolta che in una serie di cartelle di campioni annidate, si voglia eseguire una ricerca e applicarvi dei filtraggi. Pertanto, è possibile eseguire una ricerca ricorsiva per tutti i campioni contenuti in ogni sottocartella di una data cartella aggiungendo ** alla fine del percorso:

samps = "/path/to/nested/samples/**"
sample samps, 0

Fai attenzione quindi, perché la ricerca all’interno di un gruppo di cartelle ampio può impegare parecchio tempo ad essere portata a termine. Comunque, il contenuto di tutte le cartelle sorgenti sono memorizzati nella cache, quindi soltanto la prima volta la ricerca impiegherà più tempo.

Infine, tieni presente che la sorgente deve essere inserita prima. Ne nessuna sorgente viene indicata, allora il gruppo di campioni già presenti nel sistema verrà selezionato automaticamente per la sessione.

Filtri

Quando avrai ottenuto una lista di campioni da usare durante la sessione, puoi quindi utilizzare le seguenti chiavi per ridurne ulteriormente il numero:

La stringa "foo" filtrerà le occorrenze all’interno del nome del file (cartella di percorso ed estensione escluse). L’espressione regolare /fo[oO]/ filtrerà il pattern riconosciuto nel nome del file (cartella di percorso ed estensione esclusi). La parola chiave :foo filtrerà i vari file candidati se la parola chiave avrà riscontro diretto nel nome del file (cartella di percorso ed estensione esclusi). I Procs lambda{|a| ... } (ndT: in Ruby i Procs sono blocchi di codice legati a variabili locali) con un argomento saranno trattati come filtri o funzioni di generazione. La lista dei file correnti candidati deve essere passata all’oggetto che restituirà una nuova lista di candidati (una lista di percorsi validi ai file). I numeri 1 selezioneranno il file candidato a quell’indice (ripartendo dall’inizio se necessario).

Per esempio, possiamo filtrare tutti i campioni in una cartella che contengono la stringa "foo" e riproduttre il primo risultato a metà della velocità:

sample "/path/to/samples", "foo", rate: 0.5

Vedi il capitolo relativo ai sample nel manuale per altri esempi di utilizzo. Attenzione: verrà rispettato l’ordine dei filtri.

Compositi

Infine, puoi usare delle liste sia al posto delle fonti che dei filtri. Le liste saranno automaticamente appiattite e il loro contenuto sarà trattato come una fonte o un filtro. Per questo motivo, i seguenti esempi su sample sono equivalenti a livello semantico:

sample "/path/to/dir", "100", "C#"
sample ["/path/to/dir", "100", "C#"]
sample "/path/to/dir", ["100", "C#"]
sample ["/path/to/dir", ["100", ["C#"]]]

Conclusione

Questa era una sezione per coloro che hanno bisogno di manipolare e usare i pacchetti di campioni in modo avanzato. Se per te questa sezione non aveva alcun senso, non ti preoccupare. Probabilmente non hai ancora bisogno di utilizzare queste funzionalità. In ogni caso ora sai dove si trova questa sezione e potrai tornare indietro a rileggerla quando ne avrai bisogno.


4 - Randomizzazione

Un modo molto efficace per rendere interessante la tua musica è utilizzare numeri casuali. Sonic Pi ha delle funzioni che ti permettono di introdurre un po’ di casualità all’interno della tua musica ma, prima di cominciare, dovete conoscere un’importante verità: in Sonic Pi i numeri casuali non sono veramente casuali. Che significa? Vediamo insieme.

Ripetibilità

Una delle funzioni per avere numeri casuali è rrand che restituisce un valore compreso tra due numeri, un minimo e un massimo. (rrand è l’abbreviazione di ranged random, ovvero una casualità tra una serie di valori). Proviamo a suonare una nota casuale:

play rrand(50, 95)

Wow, abbiamo suonato una nota a caso. La nota suonata è 83.7527. Un numero casuale tra 50 e 95. Ehi, un momento, ho appena predetto il valore esatto della nota casuale che hai suonato anche tu? Sta succedendo qualcosa di strano. Prova a eseguire nuovamente il codice. È uscito ancora 83.7527? Non può essere casuale!

La risposta è che non è realmente casuale, è pseudo-random. Sonic Pi restituirà sempre dei valori pseudo-casuali in un modo ripetibile. Questo è utile per essere sicuri che la musica create sulla nostra macchina suonerà identica su qualsiasi altro computer, anche utilizzando un po’ di casualità nella nostra composizione.

Ovviamente, in un brano musicale, se venisse scelto in modo “casuale” sempre il valore 83.7527 non sarebbe interessante. Comunque non sempre restituirà quel risultato. Prova con il seguente codice:

loop do
  play rrand(50, 95)
  sleep 0.5
end 

Evviva! Finalmente suona casuale. Se richiamiamo più volte la funzione random, otterremo in cambio valori davvero casuali. Ricorda comunque che al successivo avvio, otterremo la stessa sequenza di numeri casuali per cui suonerà esattamente nello stesso modo. È come se il codice scritto in Sonic Pi andasse indietro nel tempo tornando allo stesso punto di inizio ogni volta che premiamo il pulsante di avvio. È il giorno della marmotta nella sintesi musicale!

Campane stregate

Un bell’esempio dell’utilizzo di valori casuali è nel seguente codice, chiamato “Campane stregate” che esegue una ripetizione del campione :perc_bell con valori casuali di velocità (rate) e pausa (sleep) tra i vari suoni di campana:

loop do
  sample :perc_bell, rate: (rrand 0.125, 1.5)
  sleep rrand(0.2, 2)
end

Cutoff (taglio di frequenze) casuale

Un altro esempio sull’utilizzo di valori casuali può essere applicato al taglio di frequenze su un sintetizzatore. Un ottimo synth con cui provarlo è l’emulatore :tb303:

use_synth :tb303
loop do
  play 50, release: 0.1, cutoff: rrand(60, 120)
  sleep 0.125
end

Semi casuali

E se non ci piacesse la sequenza casuale generata da Sonic Pi? Ovviamente è possibile scegliere un punto di partenza diverso utilizzando use_random_seed. Il seme di default è 0; puoi utilizzare semi differenti per ottenere effetti casuali diversi!

Prova con questo esempio:

5.times do
  play rrand(50, 100)
  sleep 0.5
end

Ogni volta che avvierai questo codice, sentirai la stessa sequenza di 5 note. Per avere una sequenza differente, proviamo a cambiare il seme:

use_random_seed 40
5.times do
  play rrand(50, 100)
  sleep 0.5
end

Questo codice produrrà una sequenza di 5 note diversa dalla precedente. Cambiando il seme e ascoltando il risultato ottenuto possiamo trovare qualcosa che ci piace e quando lo condivideremo con altre persone, loro ascolteranno sempre la stessa identica cosa.

Allora, diamo un’occhiata ad alcune funzioni casuali.

choose (scegli)

Un’opzione molto utile è quella di scegliere in oggetto a caso da una lista di oggetti già conosciuti. Per esempio, potrei voler suonare una nota dal seguente elenco: 60, 65, 72. Posso ottenere questo risultato con la funzione ‘choose’ che mi permette di scegliere un oggetto da una lista. Prima di tutto, devo mettere i miei numeri in una lista che può essere creata inserendo i numeri all’interno di parentesi quadre, separati da virgole. Così: ‘[60,65,72]’. Successivamente, è sufficiente attivare la funzione ‘choose’:

choose([60, 65, 72])

Ascoltiamo che cosa ne è venuto fuori:

loop do
  play choose([60, 65, 72])
  sleep 1
end

rrand (Funzione random)

Abbiamo già visto la funzione ‘rrand’, ma proviamo a riavviarla di nuovo. Il risultato è un numero casuale contenuto all’interno di due valori. Questo significa che non otterremo mai il valore esatto dei due numeri estremi ma sempre numeri contenuti in questo intervallo. I numeri saranno sempre dei numeri decimali, ovvero non dei numeri interi ma piuttosto delle frazioni di un numero. Per esempio, proviamo a osservare i numeri che escono da: ‘rrand(20,110)’:

87.5054931640625 86.05255126953125 61.77825927734375

rrand_i (numeri interi casuali)

Può capitare di avere bisogno di un numero casuale che sia intero e non decimale. Qui entra in gioco la funzione rrand_i. Funziona in modo simile a rrand con la differenza che può restituire il valore minimo e massimo come possibili valori (si tratta, infatti, di una funzione inclusiva). Questi sono degli esempi di valori restituiti da rrand_i(20, 110):

88 86 62

rand

Questa funzione restituirà un numero compreso tra 0 (incluso) e il valore massimo specificato (escluso). Di default restituirà un valore compreso tra 0 e 1. Ad esempio, può essere usata per scegliere un valore casuale per amp::

loop do
  play 60, amp: rand
  sleep 0.25
end

rand_i

Dal momento che rrand_i e rrand si comportano in modo simile, rand_i restituirà un numero intero compreso tra 0 e il valore massimo specificato.

dice (ndT: dado)

A volte vuoi simulare il lancio di un dato. Questo è un caso specifico della funzione rrand_i dove il valore più basso è sempre 1. Quando utilizziamo la funzione dice dobbiamo specificare il numero di facce del dado. Un dado comune ha 6 facce, quindi dice(6) può restituire i valori 1, 2, 3, 4, 5 oppure 6. Ciononostante, come avviene nei giochi di ruolo fantasy, può capitare di usare dadi a 4 facce, a 12, 20 oppure a 120!

one_in

Infine può capitare di voler simulare l’uscita del punteggio più alto di un dado (6, nel caso di un dado comune). La funzione one_in restituisce true con una probabilità di uno sul numero di facce del dado. Di conseguenza one_in(6) restituirà true con una probabilità di 1/6 e false negli altri casi. I valori true e false sono molto utili quando si utilizzano i costrutti if di cui parleremo più avanti.

È arrivato il momento di sperimentare un po’ di casualità nel tuo codice!


5 - Strutture di programmazione

Adesso che hai imparato come creare i suoni attraverso l’uso delle funzioni ‘play’ e ‘sample’ e che hai creato semplici melodie e ritmi utilizzando la funzione ‘sleep’ combinata con le precedenti, ti starai chiedendo che cos’altro può offrirti il mondo della programmazione…

Bene, ti aspetta qualcosa di davvero eccitante! Ci risulta che le strutture basilari della programmazione, come i concetti di loop, condizionali, funzioni e catene ti mettono in mano degli strumenti davvero potenti per esprimere le tue idee musicali.

Cominciamo a vedere come funzionano questi elementi di base…


5.1 - Blocchi

Una struttura che vedrai molto spesso utilizzando Sonic Pi è il blocco. I blocchi ci permettono di fare delle cose molto utili con pezzi di codice notevolmente lunghi. Per esempio, abbiamo visto come con i parametri dei sintetizzatori e dei campioni eravamo in grado di cambiare qualcosa che accadeva soltanto all’interno di una singola linea di programma. Però a volte potremmo voler fare qualcosa che abbia effetto su diverse linee di programma e non una sola. Per esempio, potremmo volerle mettere in loop, aggiungerci un riverbero, avviarlo soltanto una volta ogni cinque cicli e così via. Prendi in considerazione il codice che segue:

play 50
sleep 0.5
sample :elec_plip
sleep 0.5
play 62

Per fare qualcosa con un pezzo di codice, dobbiamo dire a Sonic Pi dove il blocco inizia e finisce. Per indicare l’inizio, il linguaggio di Sonic Pi utilizza il termine ‘do’ mentre per indicare la fine utilizza il termine ‘end’. Per esempio:

do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Tuttavia, questo ancora non è completo e infatti non è funzionante (prova tu stesso/a ad avviarlo e otterrai un errore). Infatti non abbiamo detto a Sonic Pi cosa deve fare con il blocco in questione. Dobbiamo indicare l’azione da compiere scrivendo un codice particolare dopo il ‘do’. Vedremo una serie di esempi in seguito, all’interno di questa guida. Per il momento è importante sapere che avvolgendo il codice all’interno di ‘do’ e ‘end’ comunichi a Sonic Pi la tua intenzione di fare qualcosa di particolare con quelle linee di codice.


5.2 - Iterazioni e anelli

Fino a questo momento, abbiamo passato molto tempo a spiegare i differenti suoni che puoi ottenere utilizzando le funzioni ‘play’ e ‘sample’. Hai anche imparato come scansionare il tempo tra i suoni attraverso la funzione ‘sleep’.

Come avrai probabilmente scoperto, puoi divertirti un sacco con questi blocchi basilari. Tuttavia, quando comincerai a utilizzare il potere del codice per strutturare le tue composizioni e la tua musica, tutta una nuova dimensione di divertimento ti si aprirà davanti. Nelle prossime sezioni, illustreremo alcuni di questi potenti strumenti. I primi saranno le iterazioni e gli anelli.

Ripetizione

Hai mai scritto una stringa di codice che ti piacerebbe ripetere alcune volte? Per esempio, qualcosa tipo:

play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25

Che cosa dobbiamo fare se vogliamo ripetere questo codice tre volte? Bene, potremmo semplicemente copiarlo e incollarlo per tre volte di seguito:

play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25
play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25
play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25

Certo che è proprio un codice lunghissimo! Che cosa accadrebbe se tu volessi cambiare il campione indicato con ‘elec_plip’? Dovresti trovare tutti i punti in cui è menzionato l’originale, cioè ‘elec_blup’, e cambiarlo. Ma ancora peggio, che cosa accadrebbe se tu volessi ripetere il codice originale per 50 o adirittura 1000 volte? A questo punto avresti un codice enorme, con un sacco di linee da variare se tu volessi effettuare un qualsiasi cambiamento.

Iterazione

Ripetere più volte una o più stringhe di codice può essere semplice come dire fai questo tre volte. Alla fine, è proprio questo che faremo. Ti ricordi del nostro vecchio amico chiamato blocco di codice? Possiamo utilizzarlo per indicare l’inizio e la fine di un gruppo di codice che vogliamo ripetere per tre volte. Quindi, invece di scrivere fai questo tre volte, noi scriveremo ‘3.times do’. Non è troppo difficile, vero? Devi solo ricordare di scrivere ‘end’ alla fine del codice che vuoi ripetere:

3.times do
  play 50
  sleep 0.5
  sample :elec_blup
  sleep 0.5
  play 62
  sleep 0.25
end

Non è molto più facile che fare copia e incolla? Possiamo usare questa struttura per creare un sacco di strutture interessanti fatte con la ripetizione:

4.times do
  play 50
  sleep 0.5
end
8.times do
  play 55, release: 0.2
  sleep 0.25
end
4.times do
  play 50
  sleep 0.5
end

Intrecciare le iterazioni

Possiamo anche mettere le iterazioni una dentro l’altra per creare delle strutture interessanti. Per esempio:

4.times do
  sample :drum_heavy_kick
  2.times do
    sample :elec_blip2, rate: 2
    sleep 0.25
  end
  sample :elec_snare
  4.times do
    sample :drum_tom_mid_soft
    sleep 0.125
  end
end

Creare anelli (loop)

Se volessi che un blocco di codice si ripetesse tante volte, potresti trovare utile l’utilizzo di numeri grandi come ‘1000.times do’. In questi casi, però, faresti forse meglio a dire a Sonic Pi di ripetere il blocco all’infinito (o almeno finché non premi stop!). Proviamo a creare un anello con il campione amen_break:

loop do
  sample :loop_amen
  sleep sample_duration :loop_amen
end

Un’aspetto importante da sapere degli anelli è che essi si comportano come dei buchi neri per il codice. Infatti, una volta che il codice entra in un anello, non riesce più a uscirne finché non premi stop. Il codice continuerà a girare in cerchio all’infinito. Quindi, se hai scritto del codice successivamente a un anello, questo non verrà mai eseguito. Nel caso seguente il piatto scritto dopo l’anello non suonerà mai:

loop do
  play 50
  sleep 1
end
sample :drum_cymbal_open

Adesso puoi cominciare a strutturare il tuo codice inserendo le iterazioni e gli anelli, vai!


5.3 - Condizionali

Una cosa che probabilmente vorrai fare è non soltanto suonare note casuali (se vuoi riguardati la sezione precedente sulla casualità) ma anche prendere decisioni casuali e basate sul risultato ottenuto da una o un’altra stringa di codice precisa. Per esempio, potresti voler suonare in maniera casuale un tamburo o un piatto. Possiamo ottenere quanto detto sopra utilizzando la funzione ‘if’.

Tirare una moneta

Quindi, tiriamo una moneta: se fosse testa, suona un tamburo, se fosse croce, suona un piatto. Facile no? Possiamo imitare il comportamento del lancio di una moneta con la funzione ‘one_in’ (introdotto nella sezione sulla casualità) specificando la probabilità di 1 ogni 2: ‘one_in(2)’. Possiamo quindi utilizzare i risultati di questa funzione per decidere quali di due stringhe di codice scegliere, quello del tamburo o quello del piatto:

loop do
  if one_in(2)
    sample :drum_heavy_kick
  else
    sample :drum_cymbal_closed
  end
  
  sleep 0.5
  
end

Tieni conto che la struttura di ‘if’ è composta di tre parti:

La domanda da chiedere La prima scelta del codice da eseguire (se la risposta alla domanda è sì) La seconda scelta del codice da eseguire (se la risposta alla domanda è no)

Di solito all’interno dei linguaggi di programmazione, la nozione di sì è definita come ‘vera’, mentre la nozione di no è definita come ‘falsa’. Quindi dobbiamo trovare una domanda che ci dia una risposta ‘vera’ o ‘falsa’, il che è esattamente quello che la funzione ‘one_in’ fa.

Fai caso a come la prima scelta è inclusa tra la parola ‘if’ e la parola ‘else’ e invece la seconda scelta è tra ‘else’ e ‘end’. Funziona ugualmente alla struttura ‘do/end’, dove puoi inserire più linee di codice in ogni posizione. Per esempio:

loop do
  if one_in(2)
    sample :drum_heavy_kick
    sleep 0.5
  else
    sample :drum_cymbal_closed
    sleep 0.25
  end
  
end

Nel caso precedente, abbiamo creato suoni di lunghezza diversa attraverso la funzione ‘sleep’ a seconda della scelta eseguta.

Funzione ‘if’ semplice

A volte puoi aver bisogno di creare un’opzione per eseguire una linea di codice. Puoi fare questo costruendo la struttura di ‘if’ e ponendo la domanda alla fine. Per esempio:

use_synth :dsaw
loop do
  play 50, amp: 0.3, release: 2
  play 53, amp: 0.3, release: 2 if one_in(2)
  play 57, amp: 0.3, release: 2 if one_in(3)
  play 60, amp: 0.3, release: 2 if one_in(4)
  sleep 1.5
end

Il codice scritto precedentemente suonerà un accordo composto da un numero sempre differente di note dipendente dal grado diverso di probabilità attribuito all’esecuzione di ogni nota.


5.4 - Catene

Quindi per il momento hai creato un ritmo coinvolgente e un basso che ti entra dentro. Come puoi fare a suonarli contemporaneamente? Una delle soluzioni è di intrecciarli a mano: suona un po’ di bassi, poi qualche colpo di batteria, poi ancora bassi…Tuttavia, la loro sincronizzazione può diventare presto difficile, specialmente quando cominci ad aggiungere numerosi elementi.

Che ne dici se Sonic Pi intrecciasse i vari strumenti per te, automaticamente? Bene, non ci crederai ma Sonic Pi può farlo per te! E lo può fare utilizzando una funzione speciale chiamata thread, ovvero tessitura.

Anelli infiniti

Per fare un esempio semplice, devi immaginarti che il codice che segue sia un basso che pompa e un ritmo coinvolgente:

loop do
  sample :drum_heavy_kick
  sleep 1
end
loop do
  use_synth :fm
  play 40, release: 0.2
  sleep 0.5
end

Come abbiamo detto in precedenza, gli anelli sono delle specie di buchi neri per il programma. Una volta che entri all’interno di un anello non puoi più uscirne finché non premi stop. Quindi, come facciamo a suonare entrambi gli anelli contemporaneamente? Dobbiamo dire a Sonic Pi che vogliamo iniziare diverse parti di codice nello stesso momento. Questo è quello che fa la funzione thread.

La funzione thread viene a salvarci dai buchi neri

in_thread do
  loop do
    sample :drum_heavy_kick
    sleep 1
  end
end
loop do
  use_synth :fm
  play 40, release: 0.2
  sleep 0.5
end

Abbiamo messo all’interno di una struttura ‘in_thread’, composta da un blocco do/end, il primo anello. Questo comunica a Sonic Pi di eseguire il contenuto di questo blocco esattamente nello stesso momento del codice presente dopo il blocco (che in questo caso è il secondo anello). Prova a eseguirlo e potrai sentire sia la batteria sia il basso contemporaneamente!

Proviamo adesso a inserire un synth all’inizio:

in_thread do
  loop do
    sample :drum_heavy_kick
    sleep 1
  end
end
loop do
  use_synth :fm
  play 40, release: 0.2
  sleep 0.5
end
loop do
  use_synth :zawa
  play 52, release: 2.5, phase: 2, amp: 0.5
  sleep 2
end

Ci ritroviamo con lo stesso problema di prima. Il primo anello è suonato contemporaneamente al secondo, grazie a ‘in_thread’. Però il terzo anello non viene mai eseguito. Dobbiamo quindi aggiungere un altro ‘filo’ al tessuto:

in_thread do
  loop do
    sample :drum_heavy_kick
    sleep 1
  end
end
in_thread do
  loop do
    use_synth :fm
    play 40, release: 0.2
    sleep 0.5
  end
end
loop do
  use_synth :zawa
  play 52, release: 2.5, phase: 2, amp: 0.5
  sleep 2
end

Avvii come ulteriori fili aggiunti al tessuto sonoro

Potrebbe sorprenderti il fatto che, quando premi il bottone ‘run’, in realtà stai creando un nuovo filo di codice da eseguire. Questo spiega perché quando premi il tasto più volte, il suono si sovrappone a quello che che è già in esecuzione. Visto che ogni esecuzione è un filo di codice, questi fili vengono intrecciati automaticamente.

Influenza del codice

Via via che scoprirai tutti i segreti di Sonic Pi, imparerai come questi ‘tessuti’ di suoni sono in realtà i mattoni principali con cui costruire la tua musica. Uno dei compiti principali di questi tessuti è quello di isolare la nozione di impostazioni correnti da quello degli altri orditi. Che cosa significa? Per esempio, quando associ un synth a un blocco utilizzando ‘use_synth’ stai associandolo soltanto a quel blocco e non ad altri. Vediamo un esempio:

play 50
sleep 1
in_thread do
  use_synth :tb303
  play 50
end
sleep 1
play 50

Hai sentito come il suono di mezzo era differente dagli altri? La funzione ‘use_synth’ aveva effetto soltanto sul blocco in cui era incluso e non sugli altri blocchi all’esterno.

Ereditarietà

Quando crei un nuovo filone, un nuovo ordito utilizzando ‘in_thread’, quest’ultimo erediterà automaticamente tutte le impostazioni correnti da quello precedente. Prova a dare un’occhiata qui:

use_synth :tb303
play 50
sleep 1
in_thread do
  play 55
end

Hai visto che la seconda nota è suonata con il timbro del synth ‘:tb303’ nonostante questo appartenesse a un altro blocco? Qualsiasi impostazione che viene modificata utilizzando la stringa ‘use_*’ si comporterà nello stesso modo.

Quando i fili di codice vengono creati, ereditano tutte le impostazioni dai fili ‘genitori’, ovvero quelli che li hanno generati. Tuttavia, le modifiche effettuate nel codice ‘figlio’ non hanno nessun effetto sui ‘genitori’.

Dare un nome ai diversi fili

Per concludere, se vogliamo, possiamo dare dei nomi ai nostri fili di codice:

in_thread(name: :bass) do
  loop do
    use_synth :prophet
    play chord(:e2, :m7).choose, release: 0.6
    sleep 0.5
  end
end
in_thread(name: :drums) do
  loop do
    sample :elec_snare
    sleep 1
  end
end

Dai uno sguardo alla sezione di destra quando esegui questo codice. Qui vengono visualizzati tutti i codici eseguiti. Vedi come questo ‘diario’ riporta il nome del filo da noi creato accoppiato con il messaggio?

[Run 36, Time 4.0, Thread :bass]
 |- synth :prophet, {release: 0.6, note: 47}

Un nome può essere attribuito a un solo filo

Un’ultima cosa da sapere a proposito dei nomi è che non possono essere eseguiti due fili con lo stesso nome contemporaneamente. Proviamo a dare un’occhiata a questa caratteristica. Leggi il codice seguente:

in_thread do
  loop do
    sample :loop_amen
    sleep sample_duration :loop_amen
  end
end

Vai avanti e incollalo all’interno di una finestra e premi Run. Prova a premerlo ancora un paio di volte. Ascolta per un po’ la cacofonia creata da più campioni ‘amen_break’ che suonano contemporaneamente ma fuori tempo. Bene, adesso puoi premere stop.

Questo è il comportamento che abbiamo osservato numerose volte, ovvero: se premi Run, i suoni si sovrappongono agli altri già in esecuzione. Quindi, se hai un anello e premi Run tre volte, otterrai tre strati di suono che sono eseguiti contemporaneamente.

Con i fili ai quali è stato attribuito un nome, è tutta un’altra cosa:

in_thread(name: :amen) do
  loop do
    sample :loop_amen
    sleep sample_duration :loop_amen
  end
end

Prova a premere Run numerose volte inserendo questo codice. Potrai ascoltare un solo ‘amen_break’. Puoi verificare il perché leggendo nella finestra a destra:

Visualizzerai questo messaggio ==> Skipping thread creation: thread with name :amen already exists.

Sonic Pi, che parla inglese, ti sta dicendo che il filo di codice chiamato ‘:amen’ è già in esecuzione, quindi non ne può creare un altro.

Questo comportamento potrebbe non sembrarti particolarmente utile adesso, ma invece lo sarà quando cominceremo a fare live coding, ovvero a suonare dal vivo…


5.5 - Funzioni

Quando cominci ad avere dei codici molto lunghi, potresti sentire il bisogno di organizzare e strutturare le cose per renderle più pulite e chiare da comprendere. Le funzioni sono un modo molto efficace per farlo. Ci consentono di dare un nome a un insieme di linee. Diamo un’occhiata a questa possibilità.

Definire le funzioni

define :foo do
  play 50
  sleep 1
  play 55
  sleep 2
end

Qui sopra, abbiamo definito una nuova funzione chiamandola ‘foo’. L’abbiamo fatto usando la nostra vecchia conoscenza, il blocco do/end, accoppiato alla parola magica ‘define’, seguita dal nome che abbiamo voluto dare alla funzione. Non dobbiamo per forza chiamarla ‘foo’ ma possiamo usare un nome qualsiasi, come ‘bar’, ‘baz’ o qualsiasi cosa che ci aiuti a ricordarne il ruolo, come ‘sezione_principale’ o ‘riff_principale’. Si può usare un termine in qualsiasi lingua.

Ricorda sempre di anteporre i due punti ‘:’ al nome della funzione quando vai a definirla.

Richiamare le funzioni

Una volta che abbiamo definito la nostra funzione, possiamo poi richiamarla semplicemente scrivendo il suo nome:

define :foo do
  play 50
  sleep 1
  play 55
  sleep 0.5
end
foo
sleep 1
2.times do
  foo
end

Possiamo utilizzare ‘foo’ anche dentro un blocco di iterazione o ovunque abbiamo scritto ‘play’ o ‘sample’. Questo ci permette di esprimere i nostri pensieri musicali e di creare delle parole con un senso preciso da utilizzare nelle nostre composizioni.

Le funzioni vengono ricordate anche in esecuzioni diverse

Fin qui, ogni volta che hai premuto Run, Sonic Pi ha iniziato da zero. Il sistema non conosceva niente più di quello che era scritto della finestra. Non puoi richiamare un codice tra una finestra e l’altra o tra un gruppo di codice e l’altro. Le funzioni sono diverse. Quando ne hai definita una, Sonic Pi si ricorda di lei. Prova. Cancella tutto il codice che hai scritto e sostituiscilo con questo:

foo

Premi Run e ascolta la fuzione in esecuzione. Dov’è finito il codice? Come fa Sonic Pi a sapere cosa eseguire? Sonic Pi, semplicemente, si ricorda della tua funzione, quindi anche se l’ha cancellata dalla finestra, si ricorda che cosa avevi digitato. Tutto ciò funziona soltanto se le funzioni sono state create utilizzando ‘define’ (e ‘defonce’).

Funzioni parametrizzate

Potresti essere interessato/a a sapere che, nello stesso modo in cui puoi passare da valori minimi a massimi o addittura casuali (‘rrand’), puoi insegnare alle tue funzioni ad accettare degli argomenti. Prova a dare un’occhiata a quanto segue:

define :my_player do |n|
  play n
end
my_player 80
sleep 0.5
my_player 90

Quanto presentato non è molto eccitante, ma illustra bene la questione. Abbiamo creato la nostra personale versione di ‘play’ chiamata ‘my_player’ che è stata poi sottoposta a dei parametri.

I parametri devono essere scritti successivmente al ‘do’ del blocco do/end ‘define’. Devono essere inclusi nelle barre verticali ‘ ’ ed essere separati dalle virgole ‘,’. Puoi usare una qualsiasi parola a tuo piacimento per dare il nome ai parametri.

La magia accade sempre all’interno del blocco do/end ‘define’. Puoi usare anche i nomi dei parametri come se fossero dei valori reali. Nell’esempio precedente noi stavamo suonando la nota ‘n’. Puoi considerare i parametri come una sorta di promessa che quando il codice è in esecuzione, essi verranno sostituiti con valori reali. Puoi fare ciò passando un parametro a una funzione quando lo richiami. Scrivendo il codice precedente, quanto detto è stato ottenuto digitando ‘my_player 80’ per suonare la nota corrispondente. All’interno della definizione della funzione, ‘n’ è sostituito con 80. Quindi se scrivi ‘play n’ la n verrà sostituita con 80. Se richiamassi di nuovo questa funzione scrivendo ‘my_player 90’, il valore n diventerebbe 90 e quindi scrivendo ‘play n’ otteniamo questa volta lo stesso suono di ‘play 90’.

Ma guardiamo un esempio più interessante:

define :chord_player do |root, repeats| 
  repeats.times do
    play chord(root, :minor), release: 0.3
    sleep 0.5
  end
end
chord_player :e3, 2
sleep 0.5
chord_player :a3, 3
chord_player :g3, 4
sleep 0.5
chord_player :e3, 3

Qui abbiamo digitato ‘repeats’ come se fosse un numero nella linea ‘repeats.times do’. Abbiamo inserito ‘roots’ come se fosse un nome di una nota all’interno dell’esecuzione di ‘play’.

Guarda come, grazie alle funzioni, riusciamo a scrivere qualcosa di molto espressivo, semplice da leggere e che compatta tutti i nostri ragionamenti!


5.6 - Variabili

Una cosa che può risultarti utile è quella di creare nomi da assegnare alle cose. Sonic Pi rende questo processo molto semplice: basta che scrivi il nome desiderato, il segno uguale (‘=’), e dopo la cosa che vuoi ricordarti:

sample_name = :loop_amen

Nell’esempio sopra ci siamo ‘ricordati’ il simbolo ‘:loop_amen’ grazie alla variabile ‘sample_name’. Adesso, possiamo utilizzare ‘sample_name’ ovunque avremmo usato ‘:loop_amen’. Ecco un esempio:

sample_name = :loop_amen
sample sample_name

Ci sono tre ragioni principali che rendono utile l’impiego di variabili in Sonic_Pi: comunicare significati, organizzare le ripetizioni e catturare i risultati delle cose.

Comunicare i significati

Quando programmi è facile pensare semplicemente che stai dicendo al computer come fare qualcosa. E finché il computer capisce, va tutto bene! Tuttavia, è importante tenere a mente che non solo il computer legge il codice,ma anche altre persone potrebbero farlo per capire cosa sta succedendo. Inoltre, è probabile che tu stesso/a andrai prima o poi a rileggere il tuo codice e cercare di capire a che cosa serve. Anche se adesso qualche passaggio ti sembra ovvio, potrebbe non esserlo per qualcun altro o per te stesso/a nel futuro!

Un modo per aiutare gli altri a comprendere il tuo programma è scrivere commenti (come abbiamo visto nella sezione precedente. Un altro modo è usare dei nomi di variabili che abbiano un significato. Per esempio, guarda il codice seguente:

sleep 1.7533

Perché in questo codice è scritto il numero ‘1,7533’? Da dove salta fuori? Che cosa significa? Guarda invece questo codice:

loop_amen_duration = 1.7533
sleep loop_amen_duration

Adesso è molto più chiaro a cosa si riferisce ‘1,7533’:è la durata del campione ‘:loop_amen’! Adesso, potresti domandarti perché non scrivere semplicemente:

sleep sample_duration(:loop_amen)

Questa è certamente un modo molto semplice e carino di comunicare lo scopo di un codice.

Gestire le ripetizioni

Spesso può succedere che nel codice ci siano molte ripetizioni e quando vuoi cambiare qualcosa, è necessario farlo in molti punti. Guarda questo esempio:

sample :loop_amen
sleep sample_duration(:loop_amen)
sample :loop_amen, rate: 0.5
sleep sample_duration(:loop_amen, rate: 0.5)
sample :loop_amen
sleep sample_duration(:loop_amen)

Facciamo un sacco di cose con :loop_amen! E se volessimo sentire la stessa cosa ma con un loop diverso come, ad esempio, :loop_garzul? Saremmo costretti a trovare e rimpiazzare tutti i :loop_amencon :loop_garzul. Potresti farlo se avessi a disposizione molto tempo ma se ti stai esibendo su un palco? Spesso non hai il lusso di avere molto tempo, specialmente se non vuoi che la gente smetta di ballare.

E se avessimo scritto il codice in questo modo:

sample_name = :loop_amen
sample sample_name
sleep sample_duration(sample_name)
sample sample_name, rate: 0.5
sleep sample_duration(sample_name, rate: 0.5)
sample sample_name
sleep sample_duration(sample_name)

Questo codice fa esattamente la stessa cosa di quello di prima (prova) ma ci dà la possibilità di cambiare una riga di codice sample_name = :loop_amen in sample_name = :loop_garzul e, grazie a questa variabile magica, verrà cambiato dappertutto.

Catturare i risultati

Un buon motivo per utilizzare le variabili è la possibilità di catturare i risultati delle cose. Per esempio, magari vuoi provare a lavorare con la durata di un sample:

sd = sample_duration(:loop_amen)

Ora possiamo usare sd in ogni punto dove abbiamo bisogno della durata del camptione :loop_amen.

Un risultato ancora più importante, forse, è che una variabile ci permette di catturare il risultato quando chiamiamo play o sample:

s = play 50, release: 8

Ora che abbiamo catturato s come variabile, possiamo controllare il sintetizzatore mentre sta funzionando:

s = play 50, release: 8
sleep 2
control s, note: 62

Vedremo come controllare i sintetizzatori in modo più dettagliato più tardi in questa sezione.

Attenzione: Variabili e Thread

Mentre le variabili sono ottime per assegnare nomi alle cose ed acquisire i relativi risultati, è importante sapere che dovrebbero essere generalmente usate in locale all’interno di un thread. Per esempio, non fare questo:

a = (ring 6, 5, 4, 3, 2, 1)
live_loop :sorted do
  a = a.sort
  sleep 0.5
  puts "sorted: ", a
end
live_loop :shuffled do
  a = a.shuffle
  sleep 0.5
end

Nell’esempio di sopra, assegniamo un cerchio di numeri a un variabile a e poi l’usiamo in due live_loop (cicli dinamici) diversi. Nel primo live_loop, ogni 0.5 secondi, ordiniamo il cerchio (a (ring 1,2,3,4,5,6)) e lo stampiamo sul log. Se esegui il codice, trovi che l’elenco stampato non è sempre ordinato!. Questo forse ti sorprenderà — specialmente che a volte l’elenco viene stampato in ordine e a volte no. Questo si chiama comportamento “non-deterministico” ed è il risultato di un problema piuttosto difficile che si chiama “condizione di gara”. Il problema è dovuto al fatto che anche il secondo ciclo sta manipolando l’elenco (in questo caso, rimescolandolo) e al punto che l’elenco viene stampato, alcune volte è appena stato ordinato ed alcune volte è appena stato rimescolato. Entrambi i cicli fanno una gara di fare qualcosa differente con lo stesso variabile ed ogni volta “vince” un ciclo diverso.

Esistono due soluzioni a questo. Prima, non usare lo stesso variable in cicli o thread molteplici. Per esempio, il codice seguente sempre stamperà un elenco ordinato perché ogni ciclo ha un proprio variabile:

live_loop :shuffled do
  a = (ring 6, 5, 4, 3, 2, 1)
  a = a.shuffle
  sleep 0.5
end
live_loop :sorted do
  a = (ring 6, 5, 4, 3, 2, 1)
  a = a.sort
  sleep 0.5
  puts "sorted: ", a
end

Comunque, a volte vogliamo condividere cose fra diversi thread. Per esempio, la chiave attuale, BPM, sintetizzatore, ecc. In questi casi, la soluzione è usare il sistema speciale di stato “thread-safe” (sicuro per i thread) di Sonic Pi attraverso le funzioni get e set. Questo si descrive dopo, nella sezione 10.


5.7 - Sincronizzazione dei thread

Raggiungendo un livello avanzato di live coding e usando molte funzioni e thread simultaneamente, ti sarai accordo che è semplice fare un errore che ferma un thread. Non è un problema perché puoi sempre farlo ripartire premendo Run ma, quando si riavvierà, sarà fuori tempo rispetto al thread originale.

Ereditare il tempo

Come abbiamo discusso in precedenza, i nuovi thread creati con in_thread ereditano le impostazioni dal thread principale. Questo include, ovviamente, anche il tempo. Questo significa che i thread sono sempre a tempo quando partono in simultanea.

Tuttavia, quando fai partire un thread da solo, questo partirà con il suo tempo ed è davvero improbabile che sia sincronizzato con gli altri thread.

Segnale (cue) e sincronizzazione

Sonic Pi offre una soluzione a questo problema con le funzioni cue e sync.

La funzione cueci permette di inviare il messaggio del cuore pulsante a tutti gli altri thread. Di default, gli altri thread non sono interessati a ricevere questo messaggio e lo ignorano. È possibile, però, attivare l’interesse al segnale utilizzando la funzione sync.

La cosa importante da sapere è che sync funziona in modo simile a sleep nel senso che ferma il thread corrente per un certo periodo di tempo. La differenza è che con sleep specifichiamo quanto tempo aspettare mentre con sync non è possibile sapere quando aspetterà dal momento che sync aspetta il segnale cue da un altro thread che potrebbe essere vicino oppure lontano nel tempo.

Proviamo ad andare nel dettaglio:

in_thread do
  loop do
    cue :tick
    sleep 1
  end
end
in_thread do
  loop do
    sync :tick
    sample :drum_heavy_kick
  end
end

Qui abbiamo due thread, uno che si comporta come un metronomo e non riproduce alcun suono ma invia il segnale :tick a ogni battito. Il secondo thread è sincronizzato al messaggio tick e quando ne riceve uno, eredita il tempo del thread cuee continua a funzionare.

Di conseguenza, sentiremo il campione :drum_heavy_kick esattamente nel momento in cui l’altro thread invia il messaggio :tick, anche se i due thread non vengono avviati in contemporanea:

in_thread do
  loop do
    cue :tick
    sleep 1
  end
end
sleep(0.3)
in_thread do
  loop do
    sync :tick
    sample :drum_heavy_kick
  end
end

Quella chiamata a sleep normalmente manderebbe il secondo thread fuori fase rispetto al primo, ma, dal momento che usiamo cue e sync, sincronizziamo automaticamente i thread bypassando ogni possibile deviazione di tempo.

Nominare i segnali di cue

Sei libero di usare tutti i nomi che vuoi per i messaggi cue, non solo :tick. Devi solo assicurarti che tutti i thread siano sincronizzati sullo stesso nome, altrimenti aspetteranno all’infinito (o, fino alla pressione del pulsante di Stop).

Facciamo qualche prova con diversi nomi per cue:

in_thread do
  loop do 
    cue [:foo, :bar, :baz].choose
    sleep 0.5
  end
end
in_thread do
  loop do 
    sync :foo 
    sample :elec_beep
  end
end
in_thread do
  loop do
    sync :bar
    sample :elec_flip
  end
end
in_thread do
  loop do
    sync :baz
    sample :elec_blup
  end
end

Qui abbiamo un loop principale cue che in modo casuale invia segnali chiamati :foo, :bar o :baz. Abbiamo poi tre thread di loop con suoni differenti, ciascuno dei quali si sincronizza con quei segnali in modo indipendente. L’effetto rete fa si che sentiamo un suono ogni 0.5 battiti dal momento che ciascuno dei thread sync è sincronizzato in modo casuale con i thread cue che riproducono il campione.

Questo ovviamente funziona se ordini i thread al contrario dal momento che i thread sync aspetteranno di ricevere il cue successivo.


6 - Effetti

Uno degli aspetti più gratificante e divertente di Sonic Pi è la possibilità di aggiungere effetti ai tuoi suoni in modo semplice. Per fare un esempio, può succedere che tu voglia aggiungere un po’ di riverbero ad alcune parti del tuo brano, oppure un po’ di echo oppure distorsione e tremolo alle tue linee di basso.

Sonic Pi ti permette di aggiungere potenti effetti in modo semplice. Ti consente di collegarli in catena tra loro (così puoi passare il tuo suono prima dal distorsore, poi dall’echo e, infine, dal riverbero) e di controllare i parametri di ciascuno individualmente (in modo simile a come abbiamo fatto con synth e campioni). È possibile modificare i parametri dell’effetto mentre sta funzionando per cui, ad esempio, puoi aumentare il riverbero sul basso mentre riproduci la traccia…

Pedali da chitarra

Se tutto questo ti sembra complicato, non preoccuparti. Quando comincerai a giocare con gli effetti, diventerà tutto più chiaro. Prima di cominciare è giusto fare un’analogica con gli effetti per chitarra. Ci sono una miriade di pedali che puoi comprare: alcuni aggiungono riverbero, altri distorsione ecc… Un chitarrista connetterà la sua chitarra in un pedale (per esempio il distorsore), poi prenderà un altro cavo e collegherà in catena un pedale di riverbero. L’output del riverberò può, infine, essere collegato dentro l’amplificatore:

Guitar -> Distortion -> Reverb -> Amplifier

Questo processo è chiamato catena di effetti. Sonic Pi si comporta esattamente in questo modo. Spesso i pedali hanno manopole che permettono di controllare quanta distorsione, riverbero, echo, ecc… applicare al suono. Sonic Pi supporta anche questo tipo di controlli. Infine, puoi immaginare un chitarrista che suona mentre qualcun altro gioca con gli effetti. Sonic Pi ti permette di fare anche questo ma invece di avere qualcun altro a controllare le cose al posto tuo, ci pensa il computer.

Esploriamo gli effetti!


6.1 - Aggiungere un effetto

In questa sezione, analizzeremo un paio di effetti: riverbero e echo. Vedremo insieme come usarli, come controllare i loro parametri e come collegarli in sequenza.

Il sistema di effetti di Sonic Pi utilizza dei blocchi. Se non hai ancora letto la sezione 5.1, ti consiglio di dargli un’occhiata veloce prima di andare avanti.

Riverbero

Se vogliamo usare un riverbero, scriviamo with_fx :reverb nel nostro blocco di codice, così:

with_fx :reverb do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Prova a suonare questo codice e sentirai che c’è del riverbero. Suona bene, vero? Tutto suona bene con un po’ di riverbero.

Ora vediamo cosa succedete se abbiamo del codice al di fuori del blocco do/end:

with_fx :reverb do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end
sleep 1
play 55

Nota come la nota finale play 55 viene riprodotta senza riverbero. Questo perché è fuori dal blocco do/end, quindi non viene catturata dal riverbero.

Allo stesso modo, se riproduci un suono prima del blocco do/end, anche questi non verranno catturati dall’effetto:

play 55
sleep 1
with_fx :reverb do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end
sleep 1
play 55

Echo

Ci sono molti effetti da cui scegliere. Perché non provare con un po’ di echo?

with_fx :echo do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Uno delle caratteristiche più importanti dei blocchi di codice degli effetti è che possiamo passargli dei parametri come abbiamo già visto con play e sample. Per esempio, un parametro dell’echo con cui giocare è phase: che rappresenta la durata dell’echo in battiti. Rendiamo l’effetto più lento:

with_fx :echo, phase: 0.5 do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Ora rendiamolo più veloce:

with_fx :echo, phase: 0.125 do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Facciamo in modo che l’echo abbia un fade out più lungo impostando il valore di decay: a 8 battiti:

with_fx :echo, phase: 0.5, decay: 8 do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Nidificazione degli effetti

Un’altra caratteristica molto importante è la possibilità di nidificare gli effetti. Questo ci permette di collegare in modo semplice un effetto all’altro. Se volessimo, ad esempio, suonare un po’ di codice con l’eco e il riverbero? Facile! Inseriamo un effetto dentro l’altro:

with_fx :reverb do
  with_fx :echo, phase: 0.5, decay: 8 do
    play 50
    sleep 0.5
    sample :elec_blup
    sleep 0.5
    play 62
  end
end

Pensa all’audio che passa dall’uno all’altro. Il suono del codice all’interno del blocco do/end (ad esempio play 50) è inviato prima all’echo e poi, il suono effettato, è inviato al riverbero.

Possiamo andare a fondo con la nidificazione per generare risultati assurdi. Attenzione, però, gli effetti potrebbero richiedere molte risorse: quando nidifichi un’effetto dentro un altro, stai, di fatto, utilizzando più effetti contemporaneamente. Sii parco con gli effetti, specialmente se utilizzi piattaforme con poca potenza di calcolo come il Raspberry Pi.

Scoprire gli effetti

Sonic Pi ha al suo interno un gran numero di effetti con cui puoi giocare. Per scoprire quelli che puoi usare, clicca su FX nella parte più a sinistra di questo help. Questi sono i miei preferiti:

wobble, reverb, echo, distortion, slicer

Ora sbizzarrisciti con gli effetti e inseriscili ovunque per ottenere nuove sonorità!


6.2 - Effetti in pratica

Anche se dall’esterno possono sembrare semplici, gli effetti sono, in realtà, molto complessi al loro interno. Data la loro semplicità di utilizzo, spesso le persone ne abusano. Questo potrebbe non essere un problema se hai una macchina potente ma se, come me, usi un Rasberry Pi, devi fare attenzione a quante risorse chiedi alla macchina se vuoi essere sicuro che non ci siano interruzioni.

Guarda questo esempio:

loop do
  with_fx :reverb do
    play 60, release: 0.1
    sleep 0.125
  end
end

Con questo codice suoniamo la nota 60 con un tempo di rilascio molto breve. Siccome vogliamo del riverbero, abbiamo aggiunto un blocco di codice. Fin qui tutto bene, anche se…

Proviamo a vedere cosa fa esattamente il codice. Per prima cosa abbiamo un loop che significa che tutto quello che c’è al suo interno viene ripetuto all’infinito. Poi abbiamo un blocco with_fx. Questo significa che verrà creato un nuovo riverbero ogni ripetizione del loop. È come, sulla chitarra, avere un pedale del riverbero diverso per ogni corda. È figo poterlo fare ma non sempre è quello che vogliamo. Per esempio questo codice fa fatica a girare su un Raspberry Pi. La creazione del riverbero, l’utilizzo e il suo spegnimento sono gestiti da with_fx e questo potrebbe consumare preziosa potenza di calcolo.

Come possiamo fare per rendere il setup simile a quello dei chitarristi che hanno un pedale di riverbero dentro cui passa tutto il segnale? Molto semplice:

with_fx :reverb do
  loop do
    play 60, release: 0.1
    sleep 0.125
  end
end

Dobbiamo spostare il loop dentro il blocco with_fx. In questo modo creiamo un solo riverbero per tutte le note suonate nel nostro loop. Questo codice è molto più efficiente e funziona a meraviglia su un Rasberry Pi.

Un compromesso potrebbe essere usare with_fx in un’iterazione dentro a un loop:

loop do
  with_fx :reverb do
    16.times do
      play 60, release: 0.1
      sleep 0.125
    end
  end
end

In questo modo abbiamo tolto with_fx dalla parte interna del loop e creiamo un riverbero ogni 16 note.

Questo è un modo di fare talmente comune che with_fx lo supporta come opzione senza la necessità di scrivere un blocco di ripetizione 16.times:

loop do
  with_fx :reverb, reps: 16 do
    play 60, release: 0.1
    sleep 0.125
  end
end

I blocchi di codice con reps: 16 e 16.times do funzionano allo stesso modo. Quello con reps: 16 in pratica ripete il codice nel blocco do/end 16 volte per cui puoi usare entrambi i sistemi in modo intercambiabile scegliendo quello che preferisci.

Ricorda: non ci sono errori, solo possibilità. Tuttavia alcuni di questi approcci genereranno suoni e performance differenti. Fai un po’ di prove e trova l’approccio che, secondo te, suona meglio tenendo sempre in considerazione la questione delle performance della tua piattaforma.


7 - Controllare i suoni durante la riproduzione

Finora abbiamo visto come lanciare synth e campioni e come cambiare i loro parametri di default come il volume, il pan, l’inviluppo ecc… Ogni suono lanciato è, essenzialmente, un singolo suono con la sua lista di opzioni di durata.

Non sarebbe bello poter cambiare i parametri di un suono mentre viene riprodotto, proprio come se stessimo facendo un bending sulla corda di una chitarra?

Siete fortunati, questa sezione vi spiegherà esattamente come farlo.


7.1 - Controllare i sintetizzatori in riproduzione

Finora ci siamo preoccupati solo di lanciare nuovi suoni ed effetti. Ciononostante Sonic Pi ci dà la possibilità di manipolare e controllare tutti i suoni in riproduzione. Lo possiamo fare utilizzando una variabile:

s = play 60, release: 5

Qui abbiamo una variabile locale s che rappresenta il sintetizzatore che suona la nota 60. Nota bene: si tratta di una variabile locale che non può essere richiamata da altre funzioni.

Ora che abbiamo s, possiamo cominciare a controllarlo utilizzando la funzione control:

s = play 60, release: 5
sleep 0.5
control s, note: 65
sleep 0.5
control s, note: 67
sleep 3
control s, note: 72

Notiamo come non stiamo utilizzando 4 synth differenti, stiamo utilizzando un solo sintetizzatore cambiando il pitch della nota 3 volte mentre sta suonando.

Possiamo passare tutti i parametri standard attraverso control, per cui possiamo controllare cose come amp:, cutoff: oppure pan:.

Parametri non controllabili

Alcuni parametri non possono essere modificati una volta che il synth è partito, per esempio l’inviluppo ADSR. Puoi scoprire quali parametri puoi modificare guardando nella documentazione. Se trovi scritto non può essere modificato una volta impostato, saprai che non puoi modificarlo una volta avviato il synth.


7.2 - Controllare gli effetti

È possibile controllare anche gli effetti, anche se bisogna farlo in modo leggermente differente:

with_fx :reverb do |r|
  play 50
  sleep 0.5
  control r, mix: 0.7
  play 55
  sleep 1
  control r, mix: 0.9
  sleep 1
  play 62
end

Invece di utilizzare una variabile, utilizziamo un parametro di riferimento nel blocco do/end. Dentro le barre |, dobbiamo specificare un nome univoco per ogni effetto che poi richiamiamo all’interno del blocco do/end. Questo comportamento è identico all’utilizzare funzioni parametrizzate.

Ora prova a controllare qualche synth ed effetto!


7.3 - Parametri scorrevoli

Esplorando i parametri dei synth e degli effetti avrai notato come alcuni di essi terminano con _slide. Magari hai anche provato a richiamarli ma senza alcun risultato. Questo succede perché, a differenza dei normali parametri, funzionano solo quando controlli il synth come discusso nella sezione precedente.

Considera il seguente esempio:

s = play 60, release: 5
sleep 0.5
control s, note: 65
sleep 0.5
control s, note: 67
sleep 3
control s, note: 72

Puoi sentire il pitch del sintetizzatore cambiare a ogni chiamata di control. Può capire, però, che ci sia uno slide tra i vari cambiamenti. Siccome stiamo controllando il parametro note:, per aggiungere lo scorrimento, dobbiamo impostare il parametro note_slide:

s = play 60, release: 5, note_slide: 1
sleep 0.5
control s, note: 65
sleep 0.5
control s, note: 67
sleep 3
control s, note: 72

Ora sentiamo che la nota viene “piegata” ogni volta che control viene richiamato. Suona bene, vero? Possiamo velocizzare lo slide utilizzando un tempo inferiore come note_slide: 0.2 o rallentarlo usando valori più lunghi.

Ogni parametro che puoi controllare, ha un parametro corrispettivo _slide con cui puoi giocare.

Lo scorrimento è delicato

Ogni volta che imposti un parametro _slide su un synth in riproduzione, verrà ricordato e usato ogni volta che scorri il parametro corrispondente. Per fermare lo slide, devi impostare il valore di _slidea 0 prima del successivo control.

Parametri di scorrimento degli effetti

È possibile controllare lo scorrimento degli effetti:

with_fx :wobble, phase: 1, phase_slide: 5 do |e|
  use_synth :dsaw
  play 50, release: 5
  control e, phase: 0.025
end

Ora possiamo divertirci utilizzando lo scorrimento per creare transizioni più fluide…


8 - Strutture di dati

Uno strumento molto utile nella cassetta degli attrezzi di un programmatore sono le strutture di dati.

Può capitare che tu voglia rappresentare o usare più di una cosa. Per esempio, può essere utile avere una serie di note che suonano una dopo l’altra. I linguaggi di programmazione utilizzano le strutture di dati proprio per questo.

Ci sono moltissime strutture di dati a disposizione dei programmatori e le persone continuano a inventarsene di nuove. Tuttavia, per il momento, prendiamo in considerazione una struttura semplice: la lista.

Andiamo nel dettaglio: capiremo la sua forma base e come utilizzare le liste per scale e accordi.


8.1 - Liste

In questa sezione analizzeremo come funziona una lista come struttura di dati. Ne abbiamo accennato in precedenza nella sezione relativa alla casualità quando abbiamo scelto di suonare una nota in modo casuale da una lista:

play choose([50, 55, 62])

In questa sezione esploreremo come utilizzare le liste per accordi e scale. Prima ripassiamo come possiamo suonare un accordo: ricordi che se non usiamo sleep, tutti i suoni vengono riprodotti in contemporanea:

play 52
play 55
play 59

Proviamo a trovare altri modi di rappresentare questo codice.

Suonare una lista

Un’opzione è di inserire tutte le note in una lista: [52, 55, 59]. La nostra amata funzione play è così furba da sapere come suonare una lista di note. Provala:

play [52, 55, 59]

Ooh, si legge molto più facilmente. Suonare una lista di note non ti deve fermare dall’usare i parametri:

play [52, 55, 59], amp: 0.3

Ovviamente puoi usare anche i nomi delle note tradizionali invece che numeri MIDI:

play [:E3, :G3, :B3]

Ora, quelli di voi che hanno avuto la fortuna di studiare un po’ di teoria musicale, riconosceranno quell’accordo come Mi minore (E Minor NdT), suonato nella terza ottava.

Accedere a una lista

Un’altra caratteristica utile delle liste è la possibilità di ottenere informazioni da essa. Può sembrare un po’ strano ma non è molto più complicato che chiedere a qualcuno di aprire un libro a pagina 23. Con una lista, chiederai: qual è l’elemento all’indice 23? L’unica cosa strana è che nei linguaggi di programmazioni gli indici iniziano da 0 e non da 1.

Con gli indici nelle liste non contiamo 1, 2, 3… ma 0, 1, 2…

Proviamo a capirci di più, guarda questo esempio di lista:

[52, 55, 59]

Non c’è niente di spaventoso. Qual è il secondo elemento in quella lista? Ovviamente è 55. Facile. Vediamo se riusciamo a far rispondere il computer al posto nostro:

puts [52, 55, 59][1]

Ok, sembra qualcosa di strano che non abbiamo mai visto prima. Credimi, non c’è nulla di difficile. Ci sono tre sezioni nella linea qui sopra: la parola puts, la nostra lista 52, 55, 59, e il nostro indice [1]. Per prima cosa, usiamo puts perché vogliamo che Sonic Pi stampi nel log una risposta. Poi, gli diamo la nostra lista e, infine, l’indice richiede il secondo elemento in essa. Dobbiamo inserire il nostro indice tra parentesi quadre perché il conteggio inizia a 0, l’indice per il secondo elemento sarà 1. Guarda:

# indexes:  0   1   2
           [52, 55, 59]

Prova a far girare il codice puts [52, 55, 59][1] e vedrai 55 comparire nel log. Prova a cambiare l’indica 1 con altri valori, prova ad allungare la lista e pensa a come usare una lista nei tuoi prossimi esperimenti. Per esempio, quale struttura musicale può essere rappresentata da una serie di numeri…


8.2 - Accordi

Sonic Pi supporta anche l’uso dei nomi di accordi. Prova tu stesso/a:

play chord(:E3, :minor)

Stiamo ottenendo davvero dei bei risultati, e il codice appare molto più ordinato e piacevole di una semplice lista di elementi (oltre che essere più facilmente leggibile dalle altre persone). Quindi, quali altri accordi supporta Sonic Pi? In realtà, ne supporta molti. Prova a digitare quello che segue:

‘chord(:E3, :m7)’ chord(:E3, :minor) chord(:E3, :dim7) chord(:E3, :dom7)

Arpeggi

Possiamo semplicemente suonare gli accordi in forma di arpeggio usando la funzione ‘play_pattern’:

play_pattern chord(:E3, :m7)

Sì, è vero, questo non è molto divertente. L’arpeggio è davvero molto lento. La funzione ‘play_pattern’ suona infatti ogni nota della serie separandola con una pausa di un secondo, ovvero quindi mettendo sempre uno ‘sleep 1’ dopo ogni nota. Possiamo però utilizzare un’altra funzione, chiamata ‘play_pattern_timed’ dove si possono specificare le distanze temporali tra le note:

play_pattern_timed chord(:E3, :m7), 0.25

Possiamo anche inserire una lista di durate che verrà trattata come un circolo, ovvero ripetendola ad anello:

play_pattern_timed chord(:E3, :m13), [0.25, 0.5]

Quanto scritto è equivalente a:

play 52
sleep 0.25
play 55
sleep 0.5
play 59
sleep 0.25
play 62
sleep 0.5
play 66
sleep 0.25
play 69
sleep 0.5
play 73

Quale preferisci scrivere?


8.3 - Scale

Sonic Pi supporta anche una larga tipologia di scale. Che ne pensi di provare a suonare una scala di Do3 maggiore (C3 nel sistema anglossassone)?

play_pattern_timed scale(:c3, :major), 0.125, release: 0.1

Possiamo anche chiere di eseguire altre ottave:

play_pattern_timed scale(:c3, :major, num_octaves: 3), 0.125, release: 0.1

Proviamo invece a suonare tutte le note in una scala pentatonica?

play_pattern_timed scale(:c3, :major_pentatonic, num_octaves: 3), 0.125, release: 0.1

Note casuali

Gli accordi e le scale sono degli utilissimi strumenti per limitare la scelta di elementi casuali all’interno di qualcosa di significativo. Prova a suonare questo esempio che seleziona note casuali all’interno di una scala di Mi3 maggiore (E3):

use_synth :tb303
loop do
  play choose(chord(:E3, :minor)), release: 0.3, cutoff: rrand(60, 120)
  sleep 0.25
end

Prova a cambiare il nome dell’accordo e i limiti all’interno di cui vengono selezionate le note.

Scopri gli accordi e le scale

Per scoprire quali scale e accordi sono supportati da Sonic Pi, clicca semplicemente sul bottone ‘Lang’ a sinistra di questa guida e quindi scegli gli accordi o le scale all’interno della lista. All’interno delle informazioni del pannello principale, scorri verso il basso il cursore finché non verdrai una lunga lista di accordi e di scale.

Divertiti! E ricorda sempre: non ci sono errori, soltanto opportunità.


8.4 - Anelli

Un’altra opzione interessante sulle liste standard sono gli anelli (ring). Se conosci un po’ di programmazione, potresti aver incontrato anelli buffer o anelli array. Qui, per comodità e semplicità, utilizzeremo solo anelli.

Nella sezione precedente abbiamo visto come accedere agli elementi di una lista utilizzando il sistema dell’indice:

puts [52, 55, 59][1]

Ora, cosa succede se vogliamo l’indice 100? Beh, ovviamente non c’è nessun elemento all’indice 100 perché la lista contiene solo 3 elementi. Sonic Pi restituirà nil che significa nulla.

Tuttavia, consideriamo di avere un contatore come, ad esempio, la pulsazione corrente che viene incrementata di continuo. Creiamo il nostro contatore e la nostra lista:

counter = 0
notes = [52, 55, 59]

Possiamo usare il nostro contatore per accedere alle note nella lista:

puts notes[counter]

Bene, abbiamo 52. Ora, incrementiamo il nostro contatore per ottenere un’altra nota:

counter = (inc counter)
puts notes[counter]

Fantastico, ora abbiamo 55 e se lo facciamo di nuovo otteniamo 59. Se, però, lo facciamo ancora, non avremo più numeri nella nostra lista e otterremo nil. E se volessimo tornare all’inizio della lista e ricominciare da capo? A questo servono gli anelli.

Creare anelli

Abbiamo due modi per creare un anello. Possiamo usare ring come funzione dell’elemento o ring come parametro:

(ring 52, 55, 59)

Oppure possiamo prendere una normale lista e convertirla in un anello inviando il messaggio .ring:

[52, 55, 59].ring

Indicizzare gli anelli

Quando abbiamo un anello, possiamo usarlo esattamente come abbiamo fatto con le normali liste con l’eccezione che possiamo usare indici che sono negativi oppure di grandezza maggiore rispetto all’anello perché ripartiranno da capo e punteranno sempre a un elemento dell’anello:

(ring 52, 55, 59)[0] #=> 52
(ring 52, 55, 59)[1] #=> 55
(ring 52, 55, 59)[2] #=> 59
(ring 52, 55, 59)[3] #=> 52
(ring 52, 55, 59)[-1] #=> 59

Utilizzare gli anelli

Diciamo che vogliamo utilizzare una variabile per rappresentare il battito corrente. Possiamo usarla come indice nel nostro anello per scegliere le note da suonare o i tempi di rilascio oppure qualsiasi altra cosa che abbiamo salvato nel nostro anello, indipendentemente dal numero di battiti in cui siamo.

Scale e accordi sono anelli

Una cosa interessante da sapere è che liste restituite da scale e chord sono anche anelli e ci possiamo accedere con indici arbitrari.

Costruzione di anelli

Oltre a ring ci sono una serie di altre funzioni che costruiranno un anello per noi.

range ci invita a specificare un punto di partenza, uno di fine e la grandezza dei passi. bools ci permette di usare 1 e 0 per rappresentare variabili booleane. knit ci consente di unire una sequenza di valori ripetuti. spread crea un anello di booleani con una distribuzione euclidea.

Dai un’occhiata alla relativa documentazione per maggiori informazioni a riguardo.


8.5 - Catene di anelli

In aggiunta ai costrutti tipo range e spread, un altro modo di creare nuovi anelli è manipolando anelli esistenti.

Comandi di concatenazione

Per capirci di più, prendiamo un semplice anello:

(ring 10, 20, 30, 40, 50)

Se volessimo riprodurlo al contrario? Beh, utilizzeremo il comando .reverse per girare quell’anello:

(ring 10, 20, 30, 40, 50).reverse  #=> (ring 50, 40, 30, 20, 10)

Ora, se volessimo solo i primi tre valori dell’anello?

(ring 10, 20, 30, 40, 50).take(3)  #=> (ring 10, 20, 30)

Infine, se volessimo dei valori casuali?

(ring 10, 20, 30, 40, 50).shuffle  #=> (ring 40, 30, 10, 50, 20)

Concatenazioni multiple

Questo è già un modo per creare nuovi anelli. Tuttavia il vero potere arriva quando concateniamo assieme alcuni comandi.

Se volessimo mescolare l’anello, rimuovere 1 elemento e poi prendere i successivi 3?

Analizziamo passo dopo passo:

(ring 10, 20, 30, 40, 50) - il nostro anello inziale (ring 10, 20, 30, 40, 50).shuffle - mescoliamo - (ring 40, 30, 10, 50, 20) (ring 10, 20, 30, 40, 50).shuffle.drop(1) - rimuoviamo il primo elemento - (ring 30, 10, 50, 20) (ring 10, 20, 30, 40, 50).shuffle.drop(1).take(3) - prendiamo gli ultimi tre - (ring 30, 10, 50)

Come puoi vedere, possiamo creare una lunga catena di questi metodi semplicemente collegandoli insieme. Possiamo farlo in qualsiasi ordine vogliamo per creare nuovi anelli partendo da anelli già esistenti.

Immutabilità

Questi anelli hanno una proprietà molto potente e importante. Sono immutabili, il che significa che non possono cambiare. Questo significa che i metodi di concatenazione descritti in questa sezione non cambiano gli anelli ma ne creano di nuovi. Puoi condividere anelli tra i vari thread e cominciare a concatenarli all’interno del thread sapendo che non andrai a modificare gli altri thread in cui viene usato lo stesso anello.

Metodi di concatenazione disponibili

Questa è una lista dei metodi di concatenazione a tua disposizione:

.reverse - restituisce un anello invertito .sort - crea una versione ordinata dell’anello .shuffle - crea una versione mescolata dell’anello .pick(3) - restituisce un anello con i risultati della chiamata di .choose 3 volte .pick(3) - restituisce un anello con i risultati della chiamata di .choose 3 volte .take(5) - restituisce un anello che contiene solo i primi 5 elementi .drop(3) - restituisce un nuovo anello con tutti gli elementi eccetto i primi 3 .butlast - restituisce un nuovo anello senza l’ultimo elemento .drop_last(3) - restituisce un anello senza gli ultimi 3 elementi .take_last(6)- restituisce un nuovo anello con soltanto gli ultimi 6 elementi .stretch(2) - ripete ogni elemento nell’anello due volte .repeat(3) - ripete l’intero anello 3 volte .mirror - aggiunge all’anello una versione invertita di se stesso .reflect - come mirror ma non duplica il valore di mezzo .scale(2) - restituisce un nuovo anello con tutti gli elementi moltiplicati per 2 (suppone che l’anello contiene solo numeri)

Ovviamente, questi metodi di concatenazione accettano anche altri valori! Sentiti libero di chiamare .drop(5) invece che .drop(3) se vuoi rimuovere i primi 5 elementi.


9 - Programmare dal vivo

Uno degli aspetti più interessanti di Sonic Pi è la possibilità di scrivere e modificare il codice live per creare musica, come se stessi suonando una chitarra. Un vantaggio di questo approccio è avere più feedback mentre componi (ad esempio riproducendo continuamente un loop e continuando a modificarlo finché non suona perfetto). Ovviamente il più grande vantaggio è poter usare Sonic Pi su un palco.

In questa sezione copriremo gli aspetti fondamentali per trasformare la composizione statica in una performance dinamica.

Tieniti forte…


9.1 - Programmare dal vivo

Ora abbiamo imparato abbastanza per cominciare a divertirci. In questa sezione tireremo le somme delle cose viste fino ad ora e ti mostrerò come comporle live e trasformarle in una performance. Abbiamo bisogno di 3 ingredienti:

Essere capaci di scrivere codice che genera suoni. Essere capaci di scrivere funzioni. Essere capaci di utilizzare thread (con nomi).

Ok, cominciamo. Programmiamo live i nostri primi suoni. Per prima cosa abbiamo bisogno di una funzione che contenga il codice che vogliamo suonare. Cominciamo in modo semplice: vogliamo, ovviamente, richiamare di continuo quella funzione in un thread:

define :my_loop do
  play 50
  sleep 1
end
in_thread(name: :looper) do
  loop do
    my_loop
  end
end

Se ti sembra troppo complicato, torna indietro per rileggere le sezioni relative alle funzioni e ai thread. Non è troppo complicato se hai capito come funzionano queste cose.

Qui abbiamo la definizione di una funzione che suona la nota 50 e si ferma per un battito. Dopodiché definiamo un thread chiamato :looperche non fa altro che ripetersi chiamando my_loop.

Se riproduci questo codice, sentirai la nota 50 ripetersi…

Facciamo dei cambiamenti

Ora è dove cominciamo a divertirci. Mentre il codice sta ancora funzionando cambia 50 in un altro numero, per esempio 55, e premi il pulsante Run di nuovo. Visto? È cambiato! Live!

Non ha aggiunto un nuovo livello perché utilizziamo thread con un nome ed è possibile avere un solo thread per ciascun nome. Inoltre il suono cambia perché ridefiniamo la funzione. Abbiamo dato a :my_loop una nuova definizione. Quando il thread :looper si ripete, semplicemente chiama una nuova definizione.

Prova a cambiarlo ancora, cambia la nota, cambia il tempo di pausa. E se aggiungessimo use_synth? Per esempio cambiamolo in:

define :my_loop do
  use_synth :tb303
  play 50, release: 0.3
  sleep 0.25
end

Ora comincia a diventare interessante, ma possiamo renderlo ancora meglio. Invece di suonare sempre la stessa nota, suoniamo un accordo:

define :my_loop do
  use_synth :tb303
  play chord(:e3, :minor), release: 0.3
  sleep 0.5
end

Perché non suonare note casuali prese dall’accordo:

define :my_loop do
  use_synth :tb303
  play choose(chord(:e3, :minor)), release: 0.3
  sleep 0.25
end

O usando un valore casuale per il cutoff:

define :my_loop do
  use_synth :tb303
  play choose(chord(:e3, :minor)), release: 0.2, cutoff: rrand(60, 130)
  sleep 0.25
end

Infine, aggiungiamo un po’ di batteria:

define :my_loop do
  use_synth :tb303
  sample :drum_bass_hard, rate: rrand(0.5, 2)
  play choose(chord(:e3, :minor)), release: 0.2, cutoff: rrand(60, 130)
  sleep 0.25
end

Ora si che sta diventando interessante!

Ora, prima di cominciare a programmare dal vivo con funzioni e thread, fermati un secondo e leggi la prossima sezione su live_loop che cambierà per sempre il modo in cui programmi in Sonic Pi…


9.2 - Loop Live

Ok, questa sezione del tutorial è la vera gemma. Se hai deciso di leggere una sola sezione, dovrebbe essere questa. Se hai letto la precedente, live_loop è un modo più semplice di fare esattamente la stessa cosa evitando troppe preoccupazioni.

Se non hai letto la sezione precedente, live_loop è il modo migliore per improvvisare con Sonic Pi.

Ok, suoniamo. Prova a scrivere il seguente codice in un buffer:

live_loop :foo do
  play 60
  sleep 1
end

Ora premi il pulsante Run, sentirai un beep di base ogni battito. Niente di divertente. Ora, però, non premere Stop. Cambia 60 in 65 e premi Run di nuovo.

Whoah! È cambiato automaticamente senza perdere un colpo. Questo è live coding.

Perché non cambiarlo per farlo suonare più basso? Aggiorna il tuo codice mentre sta suonando:

live_loop :foo do
  use_synth :prophet
  play :e1, release: 8
  sleep 8
end

Poi premi Run.

Giochiamo un po’ con il cutoff:

live_loop :foo do
  use_synth :prophet
  play :e1, release: 8, cutoff: rrand(70, 130)
  sleep 8
end

Premi run di nuovo.

Aggiungiamo un po’ di batteria:

live_loop :foo do
  sample :loop_garzul
  use_synth :prophet
  play :e1, release: 8, cutoff: rrand(70, 130)
  sleep 8
end

Cambia la nota da e1 a c1:

live_loop :foo do
  sample :loop_garzul
  use_synth :prophet
  play :c1, release: 8, cutoff: rrand(70, 130)
  sleep 8
end

Ora smettila di ascoltarmi e prova a fare da solo! Divertiti!


9.3 - Live loop multipli

Guarda questo live loop:

live_loop :foo do
  play 50
  sleep 1
end

Forse ti stai chiedendo perché c’è il nome :foo. L’aggiunta del nome è importante perché significa che questo live loop è diverso da tutti gli altri.

Non possono esistere due live loop con lo stesso nome.

Questo significa che se vogliamo avere più live loop, dobbiamo assegnare loro nomi differenti:

live_loop :foo do
  use_synth :prophet
  play :c1, release: 8, cutoff: rrand(70, 130)
  sleep 8
end
live_loop :bar do
  sample :bd_haus
  sleep 0.5
end

Ora puoi aggiornare e cambiare ciascun live loop indipendentemente e tutto funziona.

Sincronizzare i live loop

Una cosa che potresti aver notate è che i live loop lavora automaticamente con il sistema dei cue (segnali di sincronizzazione) che abbiamo visto in precedenza. Ogni volta che il live loop parte, genera un nuovo evento cue con il nome del live loop. Possiamo, di conseguenza, usare sync con uno di questi cue per essere sicuri che i loop siano sincronizzati tra loro senza fermare nulla.

Prendiamo in esame questo codice mal sincronizzato:

live_loop :foo do
  play :e4, release: 0.5
  sleep 0.4
end
live_loop :bar do
  sample :bd_haus
  sleep 1
end

Vediamo se riusciamo a sistemare il timing e la sincronizzazione senza stoppare. Per prima cosa, sistemiamo il loop :foo cambiamo il fatto di sleep 1 a qualcosa tipo 0.5:

live_loop :foo do
  play :e4, release: 0.5
  sleep 0.5
end
live_loop :bar do
  sample :bd_haus
  sleep 1
end

Non abbiamo ancora finito del tutto, avrai notato come i battiti non siano perfettamente allineati. Questo perché i loop sono fuori fase. Sistemiamo il problema sincronizzandoli tra loro:

live_loop :foo do
  play :e4, release: 0.5
  sleep 0.5
end
live_loop :bar do
  sync :foo
  sample :bd_haus
  sleep 1
end

Wow, ora è tutto a tempo, senza aver fermato nulla.

Ora, andiamo avanti e programmiamo live con live loop!


9.4 - Ticchettio

Una cosa che ti troverai a fare spesso programmando live è utilizzare gli anelli. Inserirai note dentro anelli per le melodie, sleep per il ritmo, progressioni armoniche, variazioni di timbro, ecc…

Ticchettio con anelli

Sonic Pi ha uno strumento veramente utile per lavorare con gli anelli all’interno dei live_loop. È chiamato sistema di ticchettio (tick system NdT). Nella sezione relativa agli anelli, abbiamo parlato del contatore che cresce costantemente, come, ad esempio, il numero di battiti. Il ticchettio implementa questa idea. Ci permette di usare il ticchettio con gli anelli. Vediamo un esempio:

counter = 0
live_loop :arp do
  play (scale :e3, :minor_pentatonic)[counter], release: 0.1
  counter += 1
  sleep 0.125
end

Questo equivale a:

live_loop :arp do
  play (scale :e3, :minor_pentatonic).tick, release: 0.1
  sleep 0.125
end

Qui stiamo utilizzando la scala minore pentatonica di E3 ticchettando con ogni elemento. Possiamo farlo utilizzando .tick alla fine della dichiarazione della scala. Questo tick è locale in relazione al live loop per cui ogni loop può avere il suo tick indipendente:

live_loop :arp do
  play (scale :e3, :minor_pentatonic).tick, release: 0.1
  sleep 0.125
end
live_loop :arp2 do
  use_synth :dsaw
  play (scale :e2, :minor_pentatonic, num_octaves: 3).tick, release: 0.25
  sleep 0.25
end

Tick

You anche usare tick come una funzione standard e usare il suo valore come un indice:

live_loop :arp do
  idx = tick
  play (scale :e3, :minor_pentatonic)[idx], release: 0.1
  sleep 0.125
end

Tuttavia, è meglio chiamare .tick alla fine. La funzione tick viene usata quando vuoi fare cose particolari con il valore di tick e quando vuoi usare il valore dei tick per altre cose rispetto all’indice negli anelli.

Look (Guarda)

La cosa magica riguardo tick è che non solo restituisce un nuovo indice (o il valore dell’anello a quell’indice) ma fa in modo che quando viene chiamato successivamente, restituirà il valore successivo. Dai un’occhiata agli esempi nella documentazione relativa a tick per capire come lavorarci. A volte può capitare di voler vedere il valore di tick in quel momento senza incrementarlo. Questo è possibile grazie alla funzione look. Puoi chiamare look come una funzione standard oppure aggiungendo .look alla fine di un anello.

Nominare i tick

Infine, a volte hai bisogno di avere più di un tick per live loop. Questo può essere fatto assegnando un nome ai tick:

live_loop :arp do
  play (scale :e3, :minor_pentatonic).tick(:foo), release: 0.1
  sleep (ring 0.125, 0.25).tick(:bar)
end

Qui usiamo due tick: uno per le note da suonare e un altro per il tempo di sleep. Siccome sono entrambi all’interno dello stesso live loop, per tenerli separati dobbiamo assegnargli nomi unici. È lo stesso identico procedimento che abbiamo visto nel nominare i live_loop: usiamo un simbolo anticipato da :. Nell’esempio qui sopra, abbiamo chiamato un tick :foo e l’altro :bar. Se vogliamo usare look dobbiamo chiamarli col nome corretto.

Non renderlo troppo complicato

Gran parte della potenza di questo sistema di tick non è utile quando stai cominciando. Non provare a imparare tutto quello di cui abbiamo parlato in questa sezione. Per il momento concentrati sul ticchettio all’interno di uno stesso anello. Questo sarà sufficiente per darti la gioia di usare i tick all’interno dei tuoi live_loop.

Dai un’occhiata alla documentazione alla voce tick, troverai molti esempi a riguardo!


10 - Time State

È spesso utile avere informazioni che si condividono attraverso vari thread o cicli vivi. Per esempio, forse vuoi condividere l’idea della chiave attuale, BPM, o anche concetti più astratti come la “complessità” attuale (che si potrebbe interpretare diversamente in diversi thread). Non vogliamo nemmeno perdere le garanzie deterministiche quando facciamo questo. Cioè, vorremmo condividere il nostro codice con gli altri e sapere esattamente ciò che sentiranno quando lo eseguono. Alla fine della Sezione 5.6 di questa lezione, abbiamo trattato in breve la ragione perché non dobbiamo usare variabili per condividere informazioni attraverso i thread, dovuta alla perdita del determinismo (a sua volta dovuta alle condizioni di gara).

La soluzione di Sonic Pi al problema di lavorare facilmente con variabili globali in un modo deterministico è con un sistema nuovo chiamato Time State (stato temporale). Può sembrare complesso e difficile (infatti, nel Regno Unito, programmazione con thread molteplici e memoria condivisa è tipicamente una matteria al livello universitario). Ma, come vedrai, simile a suonare la prima nota, Sonic Pi facilita molto la condivisione di stato attraverso vari thread mentre mantiene i tuoi programmi thread-safe e deterministici*.

Ti presento get e set


10.1 - Set e Get

Sonic Pi ha un archivio globale di memoria chiamato Time State. Le due cose principali che fai con questo sono set (impostare) e get (richiamare) informazioni. Immergiamoci di più…

Set

Per impostare informazioni nel Time State abbiamo bisogno di due cose:

le informazioni che vogliamo impostare, un nome unico (la chiave) per le informazioni.

Per esempio, forse vogliamo impostare il numero 3000 sotto la chiave :intensity. Questo è possibile utilizzano la funzione set:

set :intensity, 3000

Possiamo usare qualsiasi nome per la chiave. Se si sono già impostate informazioni con quella chiave, il nuovo set le sostituisce:

set :intensity, 1000
set :intensity, 3000

Nell’esempio sopra, visto che abbiamo memorizzato tutti e due i numeri sotto la stessa chiave, “vince” l’ultima chiamata di set, così il numero associato con :intensity sarà 3000 perché la prima chiamata di set è in effetti soprascritta.

Get

Per recuperare informazioni dal Time State abbiamo bisogno solamente della chiave usata per fare il set; in questo caso, :intensity. Poi, basta che chiamiamo get[:intensity], che possiamo verificare facilmente stampandone il risultato sul log:

print get[:intensity] #=> stampa 3000

Nota che le chiamate a get possono restituire informazioni che erano set da una esecuzione precedente. Una volta impostata una informazione con set, è disponibile fino a quando non viene soprascritta (come sopra abbiamo rimpiazzato il valore 1000 di :intensity con 3000) o fino a quando non viene chiuso Sonic Pi.

Thread multipli

Il beneficio principale del sistema Time State è che si può usare senza rischi attraverso thread o cicli vivi. Per esempio, puoi avere un ciclo vivo che imposta informazioni ed un altro che le recupera:

live_loop :setter do
  set :foo, rrand(70, 130)
  sleep 1
end
live_loop :getter do
  puts get[:foo]
  sleep 0.5
end

Una cosa bella dell’uso di get e set in questo modo attraverso i thread è che genera sempre lo stesso risultato ogni volta che premi “Run”. Dai, provalo. Vedi se ottieni il seguente nel tuo log:

{run: 0, time: 0.0}
 └─ 125.72265625
{run: 0, time: 0.5}
 └─ 125.72265625
{run: 0, time: 1.0}
 └─ 76.26220703125
{run: 0, time: 1.5}
 └─ 76.26220703125
{run: 0, time: 2.0}
 └─ 114.93408203125
{run: 0, time: 2.5}
 └─ 114.93408203125
{run: 0, time: 3.0}
 └─ 75.6048583984375
{run: 0, time: 3.5}
 └─ 75.6048583984375

Prova ad eseguire alcune volte — vedi, è uguale ogni volta. Questo si chiama comportamento deterministico ed è importantissimo quando vogliamo condividere la nostra musica in forma di codice e sapere che la persona che la esegue sente esattamente quello che abbiamo voluto che sentisse (come un MP3 o un flusso di internet suona lo stesso per tutti gli ascoltatori).

Un Sistema Semplice di Stato Deterministico

Nella Sezione 5.6 abbiamo parlato della ragione perché usare variabili attraverso thread può causare comportamento casuale. Questo ci blocca da potere riprodurre code come questo in maniera affidabile:

## Un Esempio di Comportamento Non-Deterministico
## (dovuto a condizioni di gara causate da vari
## cicli vivi che manipolano lo stesso variabile allo
## stesso tempo).
##  
## Se esegui questo codice noterai
## che l'elenco che viene stampato non
## è sempre in ordine!
a = (ring 6, 5, 4, 3, 2, 1)
live_loop :shuffled do
  a = a.shuffle
  sleep 0.5
end
live_loop :sorted do
  a = a.sort
  sleep 0.5
  puts "sorted: ", a
end

Guardiamo come possiamo fare questo con get e set:

## Un Esempio di Comportamento Deterministico
## (nonostante accesso concorrente dello
## stato condiviso) usando il nuovo sistema
## Time State di Sonic Pi.
##
## Quando questo codice si esegue, l'elenco che
## viene stampato è sempre in ordine!
##
set :a, (ring 6, 5, 4, 3, 2, 1)
live_loop :shuffled do
  set :a, get[:a].shuffle
  sleep 0.5
end
live_loop :sorted do
  set :a, get[:a].sort
  sleep 0.5
  puts "sorted: ", get[:a]
end

Nota che questo codice è quasi uguale alla versione prima che usava un variabile. Ma quando esegui questo codice, si comporta come si aspetta con qualsiasi codice tipico di Sonic Pi — fa la stessa cosa ogni volta in questo caso, grazie al sistema Time State.

Dunque, quando si condividono informazioni fra cicli vivi e thread, usa get e set invece di variabili per avere comportamento deterministico e riproducibile.


10.2 - Sync

La sezione 5.7 ha introdotto le funzioni cue e sync, questo quando c’è da risolvere la questione della sincronizzazione dei thread. Quello che non ha chiarito però è che si tratta proprio del sistema Time State che fornisce questa funzionalità. Si dà il caso che set è in realtà una variazione di cue: esso è costruito sopra la stessa funzionalità di base, cioè quella di inserire informazioni nel sistema Time State. Inoltre, sync è anche progettato in modo tale che funzioni perfettamente con Time State - qualsiasi informazione abbiamo intenzione di memorizzare in Time State, con cui possiamo sincronizzarci. In altre parole - ci “sincronizziamo” sugli eventi ancora da inserire in Time State.

Aspettando gli Eventi

Diamo un rapido sguardo a come usare sync per attendere che nuovi eventi siano aggiunti al Time State:

in_thread do
  sync :foo
  sample :ambi_lunar_land
end
sleep 2
set :foo, 1

foo

Nota che sync attende sempre gli eventi futuri e che bloccherà il thread attuale in attesa di un nuovo evento. Inoltre, erediterà il tempo logico del thread che lo ha innescato tramite set o cue, così che può anche essere usato per la sincronizzazione del tempo.

Passing values into the Future

foo

in_thread do
  amp = sync :foo
  sample :ambi_lunar_land, amp: amp
end
sleep 2
set :foo, 0.5

Nota che i valori che vengono passati attraverso set e cue devono essere “thread safe” - ad esempio: anelli immutabili, numeri, simboli o stringhe fissate. Sonic Pi lancia un errore se il valore che stai tentando di memorizzare nel Time State è non valido.


10.3 - Pattern Matching

foo

Match any path segment

Supponiamo di voler attendere il prossimo evento che ha un percorso con tre segmenti:

sync "/*/*/*"

Questo corrisponderà a qualsiasi evento Time State con esattamente tre segmenti, questo indipendentemente dal loro nome. Per esempio:

cue "/foo/bar/baz" cue "/foo/baz/quux" cue "/eggs/beans/toast" cue "/moog/synths/rule"

Tuttavia, non corrisponderà a percorsi con meno o più segmenti. I seguenti non corrisponderanno:

cue "/foo/bar" cue "/foo/baz/quux/quaax" cue "/eggs"

Ogni * significa qualsiasi contenuto. In questo modo possiamo abbinare i percorsi con un solo segmento con /* oppure quelli con cinque segmenti con /*/*/*/*/*

Matching partial segments

foo

cue "/foo/bar/baz" cue "/foo/baz/baz" cue "/foo/beans/baz"

Tuttavia, non corrisponderebbe a quanto segue:

cue "/foo/flibble/baz" cue "/foo/abaz/baz" cue "/foo/beans/baz/eggs"

foo

Matching Nested Path Segments

foo

cue "/foo/bar/baz" cue "/foo/bar/beans/baz" cue "/foo/baz" cue "/foo/a/b/c/d/e/f/baz"

Matching Single Letters

È possibile utilizzare il carattere ? per trovare una corrispondenza con un singolo carattere, ad esempio "/?oo/bar/baz" che corrisponderà:

cue "/foo/bar/baz" cue "/goo/bar/baz" cue "/too/bar/baz" cue "/woo/bar/baz"

Matching Multiple Words

foo

cue "/foo/bar/quux" cue "/foo/beans/quux" cue "/foo/eggs/quux"

Matching Multiple Letters

foo

cue "/foo/aux/baz" cue "/foo/bux/baz" cue "/foo/cux/baz"

foo

cue "/foo/aux/baz" cue "/foo/bux/baz" cue "/foo/cux/baz" cue "/foo/dux/baz" cue "/foo/eux/baz"

Combining Matchers

When calling sync or get you are free to combine matchers in any order you see fit to powerfully match any Time State event created by cue or set. Let’s look at a crazy example:

in_thread do
  sync "/?oo/[a-z]*/**/ba*/{quux,quaax}/"
  sample :loop_amen
end
sleep 1
cue "/foo/beans/a/b/c/d/e/bark/quux/"

OSC Pattern Matching

For those curious, these matching rules are based on the Open Sound Control pattern matching specification which is explained in detail here: http://opensoundcontrol.org/spec-1_0


11 - MIDI

Once you’ve mastered converting code to music, you might wonder - what’s next? Sometimes the constraints of working purely within Sonic Pi’s syntax and sound system can be exciting and put you into a new creative position. However, sometimes it is essential to break out of the code into the real world. We want two extra things:

To be able to convert actions in the real world into Sonic Pi events to code with To be able to use Sonic Pi’s strong timing model and semantics to control and manipulate objects in the real world

Luckily there’s a protocol that’s been around since the 80s that enables exactly this kind of interaction - MIDI. There’s an incredible number of external devices including keyboards, controllers, sequencers, and pro audio software that all support MIDI. We can use MIDI to receive data and also use it to send data.

Sonic Pi provides full support for the MIDI protocol enabling you to connect your live code to the real world. Let’s explore it further…


11.1 - MIDI In

In this section we will learn how to connect a MIDI controller to send events into Sonic Pi to control our synths and sounds. Go and grab a MIDI controller such as a keyboard or control surface and let’s get physical!

Connecting a MIDI Controller

In order to get information from an external MIDI device into Sonic Pi we first need to connect it to our computer. Typically this will be via a USB connection, although older equipment will have a 5-pin DIN connector for which you’ll need hardware support for your computer (for example, some sound cards have MIDI DIN connectors). Once you’ve connected your device, launch Sonic Pi and take a look at the IO section of the Preferences panel. You should see your device listed there. If not, try hitting the ‘Reset MIDI’ button and see if it appears. If you’re still not seeing anything, the next thing to try is to consult your operating system’s MIDI config to see if it sees your device. Failing all that, feel free to ask questions in our friendly forums: https://in-thread.sonic-pi.net

Receiving MIDI Events

Once your device is connected, Sonic Pi will automatically receive events. You can see for yourself by manipulating your MIDI device and looking at the cue logger in the bottom right of the application window below the log (if this isn’t visible go to Preferences->Editor->Show & Hide and enable the ‘Show cue log’ tickbox). You’ll see a stream of events such as:

/midi:nanokey2_keyboard:0:1/note_off  [55, 64]
/midi:nanokey2_keyboard:0:1/note_on   [53, 102]
/midi:nanokey2_keyboard:0:1/note_off  [57, 64]
/midi:nanokey2_keyboard:0:1/note_off  [53, 64]
/midi:nanokey2_keyboard:0:1/note_on   [57, 87]
/midi:nanokey2_keyboard:0:1/note_on   [55, 81]
/midi:nanokey2_keyboard:0:1/note_on   [53, 96]
/midi:nanokey2_keyboard:0:1/note_off  [55, 64]

Once you can see a stream of messages like this, you’ve successfully connected your MIDI device. Congratulations, let’s see what we can do with it!

MIDI Time State

Time State

Controllare gli effetti

Now we’ve connected a MIDI device, seen its events in the cue log and discovered that our knowledge of Time State is all we need to work with the events, we can now start having fun. Let’s build a simple MIDI piano:

live_loop :midi_piano do
  note, velocity = sync "/midi:nanokey2_keyboard:0:1/note_on"
  synth :piano, note: note
end

There’s a few things going on in the code above including some issues. Firstly, we have a simple live_loop which will repeat forever running the code between the do/end block. This was introduced in Section 9.2. Secondly, we’re calling sync to wait for the next matching Time State event. We use a string representing the MIDI message we’re looking for (which is the same as was displayed in the cue logger). Notice that this long string is provided to you by Sonic Pi’s autocompletion system, so you don’t have to type it all out by hand. In the log we saw that there were two values for each MIDI note on event, so we assign the result to two separate variables note and velocity. Finally we trigger the :piano synth passing our note.

Now, you try it. Type in the code above, replace the sync key with a string matching your specific MIDI device and hit Run. Hey presto, you have a working piano! However, you’ll probably notice a couple of problems: firstly all the notes are the same volume regardless of how hard you hit the keyboard. This can be easily fixed by using the velocity MIDI value and converting it to an amplitude. Given that MIDI has a range of 0->127, to convert this number to a value between 0->1 we just need to divide it by 127:

live_loop :midi_piano do
  note, velocity = sync "/midi:nanokey2_keyboard:0:1/note_on"
  synth :piano, note: note, amp: velocity / 127.0
end

Update the code and hit Run again. Now the velocity of the keyboard is honoured. Next, let’s get rid of that pesky pause.

Removing Latency

Before we can remove the pause, we need to know why it’s there. In order to keep all the synths and FX well-timed across a variety of differently capable CPUs, Sonic Pi schedules the audio in advance by 0.5s by default. (Note that this added latency can be configured via the fns set_sched_ahead_time! and use_sched_ahead_time). This 0.5s latency is being added to our :piano synth triggers as it is added to all synths triggered by Sonic Pi. Typically we really want this added latency as it means all synths will be well timed. However, this only makes sense for synths triggered by code using play and sleep. In this case, we’re actually triggering the :piano synth with our external MIDI device and therefore don’t want Sonic Pi to control the timing for us. We can turn off this latency with the command use_real_time which disables the latency for the current thread. This means you can use real time mode for live loops that have their timing controlled by syncing with external devices, and keep the default latency for all other live loops. Let’s see:

live_loop :midi_piano do
  use_real_time
  note, velocity = sync "/midi:nanokey2_keyboard:0:1/note_on"
  synth :piano, note: note, amp: velocity / 127.0
end

Update your code to match the code above and hit Run again. Now we have a low latency piano with variable velocity coded in just 5 lines. Wasn’t that easy!

Cominciamo

Finally, as our MIDI events are going straight into the Time State, we can also use the get fn to retrieve the last seen value. This doesn’t block the current thread and returns nil if there’s no value to be found (which you can override by passing a default value - see the docs for get). Remember that you can call get in any thread at any time to see the latest matching Time State value. You can even use time_warp to jump back in time and call get to see past events…

Now You are in Control

choose (scegli)


11.2 - MIDI Out

In addition to receiving MIDI events we can also send out MIDI events to trigger and control external hardware synths, keyboards and other devices. Sonic Pi provides a full set of fns for sending various MIDI messages such as:

Note on - midi_note_on Note off - midi_note_off Control change - midi_cc Pitch bend - midi_pitch_bend Clock ticks - midi_clock_tick

There are many other supported MIDI messages too - check out the API documentation for all the other fns that start with midi_.

Connecting to a MIDI Device

In order to send a MIDI message to an external device, we must first have connected it. Check out the subsection ‘Connecting a MIDI Controller’ in section 11.1 for further details. Note that if you’re using USB, connecting to a device which you’re sending to (rather than receiving from) is the same procedure. However, if you’re using the classic DIN connectors, make sure you connect to the MIDI out port of your computer. You should see your MIDI device listed in the preferences pane.

Sending MIDI events

The many midi_* fns work just like play, sample and synth in that they send a message at the current (logical) time. For example, to spread out calls to the midi_* fns you need to use sleep just like you did with play. Let’s take a look:

midi_note_on :e3, 50

This will send a MIDI note on event to the connected MIDI device with velocity 50. (Note that Sonic Pi will automatically convert notes in the form :e3 to their corresponding MIDI number such as 52 in this case.)

If your connected MIDI device is a synthesiser, you should be able to hear it playing a note. To disable it use midi_note_off:

midi_note_off :e3

Selecting a MIDI device

By default, Sonic Pi will send each MIDI message to all connected devices on all MIDI channels. This is to make it easy to work with a single connected device without having to configure anything. However, sometimes a MIDI device will treat MIDI channels in a special way (perhaps each note has a separate channel) and also you may wish to connect more than one MIDI device at the same time. In more complicated setups, you may wish to be more selective about which MIDI device receives which message(s) and on which channel.

We can specify which device to send to using the port: opt, using the device name as displayed in the preferences:

midi_note_on :e3, port: "moog_minitaur"

We can also specify which channel to send to using the channel: opt (using a value in the range 1-16):

midi_note_on :e3, channel: 3

Of course we can also specify both at the same time to send to a specific device on a specific channel:

midi_note_on :e3, port: "moog_minitaur", channel: 5

MIDI Studio

Finally, a really fun thing to do is to connect the audio output of your MIDI synthesiser to one of the audio inputs of your soundcard. You can then control your synth with code using the midi_* fns and also manipulate the audio using live_audio and FX:

with_fx :reverb, room: 1 do
  live_audio :moog
end
live_loop :moog_trigger do
  use_real_time
  midi (octs :e1, 3).tick, sustain: 0.1
  sleep 0.125
end

(The fn midi is available as a handy shortcut to sending both note on and note off events with a single command. Check out its documentation for further information).


12 - OSC

In addition to MIDI, another way to get information in and out of Sonic Pi is via the network using a simple protocol called OSC - Open Sound Control. This will let you send messages to and from external programs (both running on your computer and on external computers) which opens up the potential for control way beyond MIDI which has limitations due to its 1980s design.

For example, you could write a program in another programming language which sends and receives OSC (there are OSC libraries for pretty much every common language) and work directly with Sonic Pi. What you can use this for is only limited by your imagination.


12.1 - Receiving OSC

Time State

A Basic OSC Listener

Let’s build a basic OSC listener:

live_loop :foo do
  use_real_time
  a, b, c = sync "/osc/trigger/prophet"
  synth :prophet, note: a, cutoff: b, sustain: c
end

In this example we described an OSC path "/osc*/trigger/prophet" which we’re syncing on. This can be any valid OSC path (all letters and numbers are supported and the / is used like in a URL to break up the path to multiple words). The /osc prefix is added by Sonic Pi to all incoming OSC messages, so we need to send an OSC message with the path /trigger/prophet for our sync to stop blocking and the prophet synth to be triggered.

Sending OSC to Sonic Pi

We can send OSC to Sonic Pi from any programming language that has an OSC library. For example, if we’re sending OSC from Python we might do something like this:

from pythonosc import osc_message_builder
from pythonosc import udp_client
sender = udp_client.SimpleUDPClient('127.0.0.1', 4560)
sender.send_message('/trigger/prophet', [70, 100, 8])

Or, if we’re sending OSC from Clojure we might do something like this from the REPL:

(use 'overtone.core)
(def c (osc-client "127.0.0.1" 4560))
(osc-send c "/trigger/prophet" 70 100 8)

Receiving from External Machines

For security reasons, by default Sonic Pi does not let remote machines send it OSC messages. However, you can enable support for remote machines in Preferences->IO->Network->Receive Remote OSC Messages. Once you’ve enabled this, you can receive OSC messages from any computer on your network. Typically the sending machine will need to know your IP address (a unique identifier for your computer on your network - kind of like a phone number or an email address). You can discover the IP address of your computer by looking at the IO section of the preferences pane. (If your machine happens to have more than one IP address, hovering the mouse over the listed address will pop up with a list of all known addresses).

Note, some programs such as TouchOSC for iPhone and Android support sending OSC as a standard feature. So, once you’re listening to remote machines and know your IP address you can instantly start sending messages from apps like TouchOSC which enable you to build your own custom touch controls with sliders, buttons, dials etc. This can provide you with an enormous range of input options.


12.2 - Sending OSC

In addition to receiving OSC and working with it using Time State, we can also send out OSC messages in time with our music (just like we can send out MIDI messages in time with our music). We just need to know which IP address and port we’re sending to. Let’s give it a try:

use_osc "localhost", 4560
osc "/hello/world"

If you run the code above, you’ll notice that Sonic Pi is sending itself an OSC message! This is because we set the IP address to the current machine and the port to the default OSC in port. This is essentially the same as posting a letter to yourself - the OSC packet is created, leaves Sonic Pi, gets to the network stack of the operating system which then routes the packed back to Sonic Pi and then it’s received as a standard OSC message and is visible in the cue logger as the incoming message /osc:127.0.0.1:4560/hello/world. (Notice how Sonic Pi automatically prefixes all incoming OSC messages with /osc and then the hostname and port of the sender.)

Sending OSC to other programs

Of course, sending OSC messages to ourselves may be fun but it’s not that useful. The real benefit starts when we send messages to other programs:

use_osc "localhost", 123456
osc "/hello/world"

In this case we’re assuming there’s another program on the same machine listening to port 123456. If there is, then it will receive a "/hello/world OSC message with which it can do what it wants.

If our program is running on another machine, we need to know its IP address which we use instead of "localhost":

use_osc "192.168.10.23", 123456
osc "/hello/world"

Now we can send OSC messages to any device reachable to us via our local networks and even the internet!


13 - Multichannel Audio

So far, in terms of sound production, we’ve explored triggering synths and recorded sounds via the fns play, synth and sample. These have then generated audio which has played through our stereo speaker system. However, many computers also have the ability to input sound, perhaps through a microphone, in addition to the ability to send sound out to more than two speakers. Often, this capability is made possible through the use of an external sound card - these are available for all platforms. In this section of the tutorial we’ll take a look at how we can take advantage of these external sound cards and effortlessly work with multiple channels of audio in and out of Sonic Pi.


13.1 - Sound In

One simple (and perhaps familiar) way of accessing sound inputs is using our friend synth by specifying the :sound_in synth:

synth :sound_in

This will operate just like any synth such as synth :dsaw with the exception that the audio generated will be read directly from the first input of your system’s sound card. On laptops, this is typically the built-in microphone, but if you have an external sound card, you can plug any audio input to the first input.

Durata

One thing you might notice is that just like synth :dsaw the :sound_in synth only lasts for 1 beat as it has a standard envelope. If you’d like to keep it open for a little longer, change the ADSR envelope settings. For example the following will keep the synth open for 8 beats before closing the connection:

synth :sound_in, sustain: 8

Aggiungere un effetto

Of course, just like any normal synth, you can easily layer on effects with the FX block:

with_fx :reverb do
  with_fx :distortion do
    synth :sound_in, sustain: 8
  end
end

If you have plugged in a guitar to your first input, you should be able to hear it with distortion and reverb until the synth terminates as expected.

You are free to use the :sound_in synth as many times as you like concurrently (just like you would do with any normal synth). For example, the following will play two :sound_in synths at the same time - one through distortion and one through reverb:

with_fx :distortion do
  synth :sound_in, sustain: 8
end
with_fx :reverb do  
  synth :sound_in, sustain: 8
end

Concatenazioni multiple

You can select which audio input you want to play with the input: opt. You can also specify a stereo input (two consecutive inputs) using the :sound_in_stereo synth. For example, if you have a sound card with at least three inputs, you can treat the first two as a stereo stream and add distortion and the third as a mono stream and add reverb with the following code:

with_fx :distortion do
  synth :sound_in_stereo, sustain: 8, input: 1
end
with_fx :reverb do  
  synth :sound_in, sustain: 8, input: 3
end

Potential Issues

However, although this is a useful technique, there are a couple of limitations to this approach. Firstly, it only works for a specific duration (due to it having an ADSR envelope) and secondly, there’s no way to switch the FX around once the synth has been triggered. Both of these things are typical requests when working with external audio feeds such as microphones, guitars and external synthesisers. We’ll therefore take a look at Sonic Pi’s solution to the problem of manipulating a (potentially) infinite stream of live audio input: live_audio.


13.2 - Programmare dal vivo

The :sound_in synth as described in the previous section provides a very flexible and familiar method for working with input audio. However, as also discussed it has a few issues when working with a single input of audio as a single instrument (such as a voice or guitar). By far the best approach to working with a single continuous stream of audio is to use live_audio.

A Named Audio Input

live_audio shares a couple of core design constraints with live_loop (hence the similar name). Firstly it must have a unique name and secondly only one live_audio stream with that name may exist at any one time. Let’s take a look:

live_audio :foo

This code will act in a similar fashion to synth :sound_in with some key differences: it runs forever (until you explicitly stop it) and you can move it to new FX contexts dynamically.

Working with FX

On initial triggering live_audio works exactly as you might expect it to work with FX. For example, to start a live audio stream with added reverb simply use a :reverb FX block:

with_fx :reverb do
  live_audio :foo
end

However, given that live_audio runs forever (at least until you stop it) it would be pretty limiting if, like typical synths, the live audio was bound within the :reverb FX for its entire existence. Luckily this is not the case and it was designed to be easy to move between different FX. Let’s try it. Run the code above to hear live audio coming directly from the first input of your sound card. Note, if you’re using a laptop, this will typically be out of your built-in microphone, so it’s recommended to use headphones to stop feedback.

reverb,

with_fx :echo do
  live_audio :foo
end

Now, hit Run, and you’ll immediately hear the audio played through the echo FX and no longer through reverb. If you wanted them both, just edit the code again and hit Run:

with_fx :reverb do
  with_fx :echo do
    live_audio :foo
  end
end

foo

Stopping live audio

Unlike standard synths, as live_audio has no envelope, it will continue running forever (even if you delete the code, just like a function is still defined in memory if you delete the code in the editor). To stop it, you need to use the :stop arg:

live_audio :foo, :stop

It can easily be restarted by calling it without the :stop arg again:

live_audio :foo

Additionally all running live audio synths are stopped when you hit the global Stop button (as with all other running synths and FX).

Stereo input

With respect to audio channels, by default live_audio acts similarly to the :sound_in synth in that it takes a single mono input stream of audio and converts it to a stereo stream using the specified panning. However, just like :sound_in_stereo it’s also possible to tell live_audio to read two consecutive audio inputs and treat them as the left and right channels directly. This is achieved via the :stereo opt. For example, to treat input 2 as the left signal and input 3 as the right signal, you need to configure the input: opt to 2 and enable stereo mode as follows:

live_audio :foo, stereo: true, input: 2

Note that once you have started a live audio stream in stereo mode, you cannot change it to mono without stopping and starting. Similarly, if you start it in the default mono mode, you can’t switch to stereo without starting and stopping the stream.


13.3 - Sound Out

So far in this section we’ve looked at how to get multiple streams of audio into Sonic Pi - either through the use of the :sound_in synth or via the powerful live_audio system. In addition to working with multiple streams of input audio, Sonic Pi can also output multiple streams of audio. This is achieved via the :sound_out FX.

Output contexts

Let’s quickly recap on how Sonic Pi’s synths and FX output their audio to their current FX context. For example, consider the following:

with_fx :reverb do    # C
  with_fx :echo do    # B
    sample :bd_haus   # A
  end
end

The simplest way to understand what’s happening with the audio stream is to start at the innermost audio context and work our way out. In this case, the innermost context is labelled A and is the :bd_haus sample being triggered. The audio for this goes directly into its context which is B - the :echo FX. This then adds echo to the incoming audio and outputs it to its context which is C - the :reverb FX. This then adds reverb to the incoming audio and outputs to its context which is the top level - the left and right speakers (outputs 1 and 2 in your audio card). The audio flows outwards with a stereo signal all the way through.

Sound Out FX

The above behaviour is true for all synths (including live_audio) and the majority of FX with the exception of :sound_out. The :sound_out FX does two things. Firstly it outputs its audio to its external context as described above. Secondly it also outputs its audio directly to an output on your sound card. Let’s take a look:

with_fx :reverb do      # C
  with_fx :sound_out, output: 3 do # B
    sample :bd_haus     # A
  end
end

In this example, our :bd_haus sample outputs its audio to its external context which is the :sound_out FX. This in turn outputs its audio to its external context the :reverb FX (as expected). However, it also outputs a mono mix to the 3rd output of the system’s soundcard. The audio generated within :sound_out therefore has two destinations - the :reverb FX and audio card output 3.

Mono and Stereo out

choose (scegli)

Direct Out

As we have also seen, the default behaviour for :sound_out and :sound_out_stereo is to send the audio both to their external context (as is typical of all FX) and to the specified output on your soundcard. However, occasionally you may wish to only send to the output on your soundcard and not to the external context (and therefore not have any chance of the sound being mixed and sent to the standard output channels 1 and 2). This is possible by using the standard FX opt amp: which operates on the audio after the FX has been able to manipulate the audio:

with_fx :sound_out, output: 3, amp: 0 do # B
  sample :loop_amen                      # A
end

In the above example, the :loop_amen sample is sent to its outer context, the :sound_out FX. This then sends a mono mix to audio card output 3 and then multiplies the audio by 0 which essentially silences it. It is this silenced signal which is then sent out to the :sound_out’s outer context which is the standard output. Therefore with this code, the default output channels will not receive any audio, and channel 3 will receive a mono mix of the amen drum break.


12 - Conclusioni

Abbiamo concluso il tutorial introduttivo di Sonic Pi. Spero che tu abbia imparato qualcosa. Non ti preoccupare se non hai capito tutto nel dettaglio, suona e divertiti. Sentiti libero di tornare indietro quando ti vengono domande su sezioni di cui abbiamo parlato in questo tutorial.

Se hai delle domande su argomenti di cui non abbiamo parlato, iscrivi al Sonic Pi forum e chiedi pure lì. Troverai qualcuno felice di darti una mano.

Infine, ti invito a dare un’occhiata al resto della documentazione presente in questo help. Ci sono cose di cui non abbiamo parlato che non vedono l’ora di essere scoperte.

Per cui suona, divertiti, condividi il tuo codice, esibisciti per i tuoi amici, mostra il tuo schermo e ricorda:

Non ci sono errori, solo opportunità.

Sam Aaron


- Articoli MagPi

L’appendice A contiene una raccolta di tutti gli articoli su Sonic Pi scritti per il magazine MagPi.

Scopri gli argomenti

Questi articoli non sono pensati per essere letti in un ordine specifico dal momento che contengono materiale che copre vari argomenti. Invece che provare a insegnarti a usare Sonic Pi per intero, ciascuno si concentra su un aspetto specifico di Sonic Pi e cerca di coprirlo in modo accessibile.

Leggi il magazine MagPi

Puoi vederli nella loro forma professionale in PDF gratuito qui: https://www.raspberrypi.org/magpi/

Suggerisci un argomento

Se non trovi un argomento di tuoi interesse in questi articoli, perché non suggerirne uno? Il modo più semplice è di twittare a @Sonic_Pi. Non si può mai sapere, magari il tuo suggerimento diventerà il prossimo articolo!


- I cinque consigli migliori

1. Non ci sono errori

La lezione più importante da imparare con Sonic Pi è che non ci sono errori. Il modo migliore di imparare è provando. Prova un sacco di cose, smettila di preoccuparti se il tuo codice suona bene o no e prova diversi synth, note, effetti e parametri. Scoprirai un sacco di cose che ti faranno divertire perché suonano in modo orribile e alcune gemme preziose che suoneranno incredibilmente. Semplicemente elimina le cose che non ti piacciono e tieni quelle che ti piacciono. Più ‘errori’ ti permetti di fare, più velocemente imparerai.

2. Usa gli effetti

Scommetto che hai imparato a utilizzare le funzioni di base di Sonic Pi come sample e play. Cosa c’è dopo? Lo sapevi che Sonic Pi ha al suo interno più di 27 effetti per cambiare il suono del tuo codice? Gli effetti sono come i filtri nei programmi di grafica solo che invece di sfocare l’immagine o trasformarla in bianco e nero aggiungono riverbero, distorsione, echo. Pensali come se stessi collegando un pedale da chitarra all’amplificatore. Per fortuna Sonic Pi rende l’utilizzo degli FX super semplice e non richiede cavi! Tutto quello che devi fare è prendere una sezione di codice e racchiuderla dentro un effetto. Proviamo con un esempio:

sample :loop_garzul
16.times do
  sample :bd_haus
  sleep 0.5
end

Se vuoi aggiungere un effetto al campione :loop_garzul, metti tutto dentro il blocco with_fx:

with_fx :flanger do
  sample :loop_garzul
end
16.times do
  sample :bd_haus
  sleep 0.5
end

Ora, se vuoi aggiungere un effetto alla cassa della batteria, inserisci anche quella dentro with_fx:

with_fx :flanger do
  sample :loop_garzul
end
with_fx :echo do
  16.times do
    sample :bd_haus
    sleep 0.5
  end
end

Ricorda: puoi inserire qualsiasi codice dentro with_fx e ogni suono creato passerà attraverso quell’effetto.

3. Controllare i sintetizzatori

Per scoprire i tuoi suoni, avrai presto bisogno di modificar e controllare i tuoi synth e gli effetti. Per esempio, magari vuoi cambiare la lunghezza di una nota, aggiungere più riverbero, cambiare il tempo tra le ripetizioni dell’eco. Sonic Pi ti permette di avere un grande livello di controllo attraverso i parametri opzionali. Vediamo velocemente come fare. Copia il seguente codice e premi Run:

sample :guit_em9

Ooh, un bellissimo suono di chitarra. Ora cominciamo a giocarci. Perché non cambiare la velocità?

sample :guit_em9, rate: 0.5

Hey, cos’è quel rate: 0.5 che ho appena aggiunto alla fine? È un parametro. Tutti i synth e gli effetti in Sonic Pi li supportano e ce ne sono un sacco con cui giocare. Sono disponibili anche per gli effetti; prova questo:

with_fx :flanger, feedback: 0.6 do
  sample :guit_em9
end

Ora, prova ad aumentare il feedback a 1 per sentire dei suoni assurdi. Leggi la documentazione per tutti i dettagli sui parametri che puoi utilizzare.

5. Programma live

Il modo migliore per sperimentare velocemente con Sonic Pi è attraverso il live code. Questo ti permette di partire con del codice e continuare a cambiarlo mentre continua a funzionare. Per esempio, se non sai cosa fa il parametro di cutoff a un campione, prova a usarlo. Copia questo codice in un workspace:

live_loop :experiment do
  sample :loop_amen, cutoff: 70
  sleep 1.75
end

Ora previ run e sentirai un suono di batteria soffocato. Ora cambia il valore di cutoff: a 80 e premi di nuovo run. Riesci a sentire la differenza? Ora prova 90, 100, 110

Una volta che capisci come usare live_loop non tornerai più indietro. Ogni volta che faccio una performance, mi baso completamente su live_loop tanto quanto un batterista si affida alle sue bacchette. Per maggiori informazioni sul live coding, guarda la sezione 9 del tutorial all’interno di Sonic Pi.

Una delle cose che amo fare con Sonic Pi è fare in modo che componga al posto mio. Un ottimo modo per farlo è utilizzare la casualità. Può sembrare complicato ma non lo è per niente. Dai un’occhiata a questo codice:

live_loop :rand_surfer do
  use_synth :dsaw
  notes = (scale :e2, :minor_pentatonic, num_octaves: 2)
  16.times do
    play notes.choose, release: 0.1, cutoff: rrand(70, 120)
    sleep 0.125
  end
end

Ora, quando suoni questo, sentirai un flusso costante di nome della scala :e2 :minor_pentatonic suonate con un synth :dsaw. Vi sento gridare: “Aspetta un momento, quella non è una melodia”. Beh, questa è la prima parte del mio trucco magico. Ogni volta che riproduciamo dall’inizio live_loop possiamo dire a Sonic Pi di resettare il flusso casuale. È come andare indietro nel tempo. Prova questo, aggiungi la linea use_random_seed 1 al live_loop:

live_loop :rand_surfer do
  use_random_seed 1
  use_synth :dsaw
  notes = (scale :e2, :minor_pentatonic, num_octaves: 2)
  16.times do
    play notes.choose, release: 0.1, cutoff: rrand(70, 120)
    sleep 0.125
  end
end

Ogni volta che il live_loop ricomincerà, i numeri random saranno resettati. Questo significa che sceglierà sempre le stesse 16 note ogni volta. Voilà, una melodia. Ora, questa è la parte interessante. Cambia il valore del seme da 1 a, diciamo, 4923. Wow! Un’altra melodia! Semplicemente cambiando un numero (quello del seme), puoi esplorare tutte le combinazioni di melodie che vuoi. Questa è magia.


- Programmare dal vivo

I raggi laser attraverso il fumo, il subwoofer che pompa i bassi nella folla. L’atmosfera riempita da sintetizzatori e persone che ballano. Tuttavia c’è qualcosa che non va in questo club. Proiettato sopra alla testa del DJ c’è del testo e non dei normali visual. È la proiezione di Sonic Pi che sta girando su Raspberry Pi. La persona che occupa la cabina del DJ non sta usando dei dischi ma sta scrivendo e modificando del codice. Live. Questo è il Live Coding.

Sam Aaron Live Coding

Questa può sembrare una storia di una notte in un club futuristico ma programmare musica è un trend in crescita ed è spesso descritto come Live Coding (http://toplap.org). Uno delle direzioni più recenti che ha preso questo approccio alla musica è l’Algorave (http://algorave.com), eventi dove gli artisti come me programmano musica affinché le persone possano ballare. Non è necessario, però, che tu sia in un nightclub per fare del live coding; con Sonic Pi v.2.6+ puoi farlo ovunque ti porti il tuo Rasberry Pi, un paio di cuffie e delle casse. Quando raggiungerai la fine di questo articoli, saprai programmare e modificare il tuo personalissimo beat. Il punto di arrivo dipenderà solo dalla tua immaginazione.

Live Loop

La chiave per programmare live con Sonic Pi è capire il funzionamento di live_loop. Proviamo a vederne uno:

live_loop :beats do
  sample :bd_haus
  sleep 0.5
end

Ci sono 4 ingredienti principali nel live_loop. Il primo: il suo nome. Il nostro live_loop qui sopra si chiama :beats. Sei libero di chiamare il tuo live_loop come vuoi. Sii creativo. Io spesso utilizzo nomi che comunichino qualcosa riguardo alla musica che stanno producendo alle persone tra il pubblico. Il secondo ingrediente è la parola do che indica dove comincia il live_loop; il terzo è la parola end che indica dove finisce e, infine, c’è il corpo del live_loop che descrive quello che verrà ripetuto: tutto ciò che è compreso tra do e end. In questo caso stiamo suonando in modo ripetitivo un campione di cassa della batteria con mezza misura di pausa. Questo produce un beat regolare. Vai avanti, copia il codice in un buffer vuoto in Sonic Pi e premi run. Boom, boom, boom!.

Ridefinire on-the-fly

Ok, cosa c’è di così importante in live_loop? Fin qui sempre un normale loop! Beh, la bellezza del live_loop è che puoi modificarli al volo. Questo significa che mentre stanno ancora andando, puoi cambiare il loro comportamento. Questo è il segreto del live coding in Sonic Pi. Proviamo:

live_loop :choral_drone do
  sample :ambi_choir, rate: 0.4
  sleep 1
end

Ora premi il pulsante Run oppure la scorciatoia Alt-r. Ora stai ascoltato il bellissimo suono di un coro. Ora, mentre sta suonando, cambia il valore rate da 0.4 a 0.38. Premi Run di nuovo. Hai sentito il cambio di nota? Cambialo di nuovo a 0.4 per farlo tornare com’era. Ora, abbassalo a 0.2, poi a 0.19 e poi riportalo a 0.4. Guarda come cambiando un parametro al volo hai il controllo della musica? Ora prova a modificare lo stesso parametro a tuo piacimento. Prova anche con numeri negativi. Divertiti!

Il tempo di sleep è importante

Una delle lezioni più importanti riguardo a live_loop è che devono riposarsi. Guarda questo codice:

live_loop :infinite_impossibilities do
  sample :ambi_choir
end

Se provi a far funzionare questo codice, Sonic Pi si lamenterà subito che live_loop non si ferma. Questo è un sistema di sicurezza! Prenditi un secondo per analizzare cosa questo codice sta chiedendo al computer di fare. Giusto, sta chiedendo di suonare un numero infinito di campioni di coro senza pausa. Senza il sistema di sicurezza il computer proverebbe ad eseguirlo e crasherebbe nel tentativo. Ricorda: i live_loop devono contenere sleep.

Combinare suoni

La musica è fatta di cose che accadono nello stesso momento. Batteria, basso, voce, chitarre… tutto in contemporanea. In informatica questo lo chiamiamo concordanza e Sonic Pi lo fa in modo molto semplice. È sufficiente usare più di un live_loop!

live_loop :beats do
  sample :bd_tek
  with_fx :echo, phase: 0.125, mix: 0.4 do
    sample  :drum_cymbal_soft, sustain: 0, release: 0.1
    sleep 0.5
  end
end
live_loop :bass do
  use_synth :tb303
  synth :tb303, note: :e1, release: 4, cutoff: 120, cutoff_attack: 1
  sleep 4
end

Qui abbiamo due live_loop, uno che crea beat velocemente e un altro, più lento, che produce strani suoni di basso.

Una delle cose interessanti riguardo i live_loop è che possono gestire individualmente il loro tempo. Questo vuol dire che è molto semplice creare strutture poliritmiche interessanti o suonare sfasati nello stile di Steve Reich. Ascolta questo:

# Piano Phase di Steve Reich
notes = (ring :E4, :Fs4, :B4, :Cs5, :D5, :Fs4, :E4, :Cs5, :B4, :Fs4, :D5, :Cs5)
live_loop :slow do
  play notes.tick, release: 0.1
  sleep 0.3
end
live_loop :faster do
  play notes.tick, release: 0.1
  sleep 0.295
end

Mettiamo tutto insieme

In ognuno di questi tutorial, finiremo con un esempio di musica che deriva dalle idee che abbiamo introdotto oggi. Leggi il codice e cerca di immaginare il risultato. Poi copialo in un buffer vuoto di Sonic Pi e premi Run e ascolta come suona. Infine, cambia uno dei numeri o utilizza i commenti. Prova a capire se puoi usarli come punti di partenza per una performance e, soprattutto, divertiti! A presto…

with_fx :reverb, room: 1 do
  live_loop :time do
    synth :prophet, release: 8, note: :e1, cutoff: 90, amp: 3
    sleep 8
  end
end
live_loop :machine do
  sample :loop_garzul, rate: 0.5, finish: 0.25
  sample :loop_industrial, beat_stretch: 4, amp: 1
  sleep 4
end
live_loop :kik do
  sample :bd_haus, amp: 2
  sleep 0.5
end
with_fx :echo do
  live_loop :vortex do
    # use_random_seed 800
    notes = (scale :e3, :minor_pentatonic, num_octaves: 3)
    16.times do
      play notes.choose, release: 0.1, amp: 1.5
      sleep 0.125
    end
  end
end

- Beat codificati

Tra gli sviluppi tecnologici che hanno avuto maggiore impatto nel mondo della musica moderna, c’è sicuramente l’invenzione dei campionatori. Inizialmente i campionatori erano degli scatolotti in grado di registrare e mantenere al proprio interno un qualsiasi suono, in maniera da poterlo manipolare e riprodurre in tanti modi diversi. Per esempio, potevi prendere una vecchia canzone, individuare un assolo di batteria, registrarlo all’interno del campionatore, e successivamente riprodurlo in ripetizione continua ad una velocità dimezzata. Questo è esattamente il modo con cui sono stati creati i primi beat hip hop e oggi è praticamente impossibile travare nella musica elettronica una canzone che non contenga in qualche modo dei “campioni”. L’utilizzo dei campioni è l’ideale per introdurre in maniera semplice e veloce interessanti elementi nella tua esibizione di live coding.

Ma quindi dove lo troviamo un campionatore? Beh, in realtà ne abbiamo già uno. E’ nel nostro Raspberry Pi! Nel cuore di Sonic Pi è integrato un campionatore molto potente: proviamo a giocarci un po’!

L’Amen Break

Uno dei campioni di batteria più conosciuti e maggiormente riconoscibili è L’Amen Break. L’Amen Break è contenuto in una canzone del 1969 intitolata “Amen Brother” eseguita dalla band americana The Winstons. “Break” in Inglese significa pausa e nella musica rappresenta un interludio strumentale che collega due parti di una canzone. Questo particolare Break fu scoperto all’inizio negli anni 80 da dei musicisti hip hop e da lì utilizzato in una grande varietà di generi musicali come drum and bass, breakbeat, hardcore techno and breakcore.

Sarai contento di sapere che questo particolare campione è già incluso in Sonic Pi. Ripulisci un buffer e scrivici dentro il seguente codice:

sample :loop_amen

Premi Run e bum! Stai ascoltando uno dei più influenti campioni di batteria della storia della musica dance! Tuttavia, questo campione non è famoso per essere suonato singolarmente, bensì per essere riprodotto all’interno di un loop.

Stretchare il beat

Eseguiamo l’Amen Break in loop facendoci aiutare dal nostro vecchio amico live_loop, già introdotto in questo tutorial:

live_loop :amen_break do
  sample :loop_amen
  sleep 2
end

Ok, è in loop, ma c’è una fastidiosa pausa ad ogni ripetizione. Questo è perché abbiamo chiesto uno sleep pari a 2 battute e con una velocità predefinita di 60 BPM, il nostro campione :loop_amen dura soltanto 1.753 battute. Quindi abbiamo un silenzio di 2 - 1.753 = 0.247 battute. Anche se è breve, risulta ben evidente.

Per risolvere questo problema, possiamo usare beat_stretch: chiedendo a Sonic Pi di “streatchare” (stiracchiare) il campione, in modo da farlo durare uno specifico numero di battute.

Le funzioni sample e synth ti danno la possibilità di avere un grande controllo attraverso i parametri opzionali amp:, cutoff: e release:. Tuttavia, il termine “parametri opzionali” è lungo e complicato da dire, quindi utilizzeremo la parola opts.

live_loop :amen_break do
  sample :loop_amen, beat_stretch: 2
  sleep 2
end  

Adesso si che si balla! Anche se, forse vorremmo rallentare o accelerare il ritmo per adattarlo al nostro umore.

Giocare con il tempo

Bene, quindi che dobbiamo fare se vogliamo cambiare stile e passare all’hip hop old school o al breakcore? Un modo semplice è di giocare con il tempo, o meglio incasinare il tempo. Con Sonic Pi è facilissimo, basta infilare un ‘use_bpm’ dentro il tuo live loop:

live_loop :amen_break do
  use_bpm 30
  sample :loop_amen, beat_stretch: 2
  sleep 2
end 

Mentre stai rappando sopra questi ritmi lenti, fai caso a come il programma rimanga fermo per 2 battiti (sleep 2) e i nostri bpm sono a 30. Quindi tutto è a tempo. L’opzione ‘beat_stretch’ funziona con i bpm di riferimento per fare in modo che tutto torni.

Quindi, qui sta la parte divertente. Mentre il loop è ancora in azione, cambia il numero ‘30’ con ‘50’ dentro ‘use_bpm 30’. Wow, tutto va più veloce e comunque rimane a tempo! Prova ad andare ancora più veloce, inserendo 80 o 120 e ora fai impazzire il computer e spacca a 200!

Filtraggio

Adesso che abbiamo imparato a mettere i campioni nel live loop, diamo un’occhiata ad alcune delle opzioni più divertenti del synth ‘sample’. Il primo è ‘cutoff:’, che controlla il filtro di taglio del campionatore. Di norma è disabilitato ma puoi facilmente attivarlo:

live_loop :amen_break do
  use_bpm 50
  sample :loop_amen, beat_stretch: 2, cutoff: 70
  sleep 2
end  

Vai avanti e cambia il ‘cutoff:’. Per esempio, aumentalo a 100, premi Run e aspetta che il loop torni all’inizio per ascoltare il risultato sonoro. I valori più bassi, tipo 50, suonano più bassi e caldi mentre valori alti tipo 100 o 120 sono più secchi. Ciò accade perché l’opzione ‘cutoff:’ taglia le frequenze alte nello stesso modo in cui una falciatrice taglia l’erba. Il valore di ‘cutoff:’ è come regolare l’altezza della falciatrice e determina quanto l’erba deve essere tagliata.

Affettare

Un altro strumento divertente è l’effetto slicer. Questo affetterà (slice in inglese) il suono. Avvolgi la linea di ‘sample’ dentro il codice di effetto, così:

live_loop :amen_break do
  use_bpm 50
  with_fx :slicer, phase: 0.25, wave: 0, mix: 1 do
    sample :loop_amen, beat_stretch: 2, cutoff: 100
  end
  sleep 2
end

Fai caso a come il suono salta sù e giù (se vuoi sentire il suono originale, senza effetti, cambia il valore di ‘mix:’ a 0). Adesso, proviamo a giocare con i valori di ‘phase:’. Questa è la frequenza (in battiti) dell’effetto di affettamento. Un valore piccolo, tipo ‘0.125’, affetterà più velocemente e uno più grande, tipo ‘0.5’, più lentamente. Senti come il dimezzamento o il raddoppiamento dei valori di ‘phase:’ tendono sempre a suonare piacevoli. Infine, cambia il valore di ‘wave:’ a 0, 1 o 2 e ascolta la differenza. I diversi numeri rappresentato le differenti forme d’onda. 0 è un’onda a dente di sega (attacco veloce e rilascio lento), 1 è un’onda quadrata ( attacco e rilascio veloce), 2 infine è un’onda triangolare (attacco e rilascio lento).

Mettiamo tutto insieme

Infine, andiamo indietro nel tempo al primo periodo drum and bass di Bristol con questo esempio. Non ti preoccupare troppo di cosa significa questa frase. Digita il codice, premi Run e comincia a fare live coding cambiando i valori delle opzioni e osserva i risultati. Mi raccomando, condividi quello che hai ottenuto. Ci vediamo la prossima volta…

use_bpm 100
live_loop :amen_break do
  p = [0.125, 0.25, 0.5].choose
  with_fx :slicer, phase: p, wave: 0, mix: rrand(0.7, 1) do
    r = [1, 1, 1, -1].choose
    sample :loop_amen, beat_stretch: 2, rate: r, amp: 2
  end
  sleep 2
end
live_loop :bass_drum do
  sample :bd_haus, cutoff: 70, amp: 1.5
  sleep 0.5
end
live_loop :landing do
  bass_line = (knit :e1, 3, [:c1, :c2].choose, 1)
  with_fx :slicer, phase: [0.25, 0.5].choose, invert_wave: 1, wave: 0 do
    s = synth :square, note: bass_line.tick, sustain: 4, cutoff: 60
    control s, cutoff_slide: 4, cutoff: 120
  end
  sleep 4
end

- Riff di synth

Sia che siano i minacciosi scivolamenti i oscillatori rumorosi, sia che siano i colpi scordati di onde a dente di sega che trapuntano il suono, il synth principale gioca un ruolo essenziale in ogni brano elettronico. Nell’edizione del mese scorso, in questa guida abbiamo trattato le modalità di programmazione dei ritmi. In questa edizione tratteremo invece di come programmare tre componenti centrali di un riff fatto con il synth: il timbro, la melodia e il ritmo.

Bene, allora accendiamo il Raspberry Pi, apriamo Sonic Pi in versione 2.6 o più recente, e mettiamoci a fare un po’ di rumore!

Possibilità trimbriche

Una parte essenziale di ogni riff fatto con il synth è di cambiare il timbro dei suoni e giocarci. In Sonic Pi, il timbro può essere controllato in due modi: cambiando totalmente synth per avere delle modifiche più radicali, cambiando le varie caratteristiche del synth che siamo utilizzando per avere delle modifiche più raffinate e precise. Possiamo utilizzare anche FX, ma questo è spiegato in un’altra guida…

Creiamo un semplice live loop dove continuiamo a cambiare il sintetizzatore usato:

live_loop :timbre do
  use_synth (ring :tb303, :blade, :prophet, :saw, :beep, :tri).tick
  play :e2, attack: 0, release: 0.5, cutoff: 100
  sleep 0.5
end

Dai uno sguardo al codice. Siamo semplicemente scorrendo attraverso una serie di nomi di synth (quando arriverai in fondo, la lista riparte da capo). Ogni nome viene selezionato attraverso la funzione ‘use_synth’, che cambierà anche il synth utilizzato all’interno del ‘live_loop’ corrente. Stiamo suonando anche la nota ‘:e2’ (E, o ‘Mi’ nel sistema italiano, alla seconda ottava), con un rilascio della nota di 0,5 battiti (mezzo secondo con i BPM preimpostati a 60) e il livello di ‘cutoff:’ impostato a 100.

Ascolta adesso come i diversi synth hanno un suono radicalmente diverso, anche se tutti suonano la stessa nota. Prova a sperimentare, cambiando il tempo di rilascio della nota (‘release:’) o cambiando anche il tempo di attacco (‘attack:’) così da capire come questi parametri hanno un forte impatto sul suono. Infine, prova a cambiare il ‘cutoff:’ per vedere come diversi valori cambiano il timbro (i valori tra 60 e 130 sono i migliori). Fai caso a quanti differenti suoni puoi creare semplicemente modificando alcuni valori. Quando avrai imparato a gestirli, vai alla scheda Synth dentro il sistema Help e qui troverai tutti i synth a disposizione e tutti i parametri che ogni synth supporta. Così ti renderai conto di quanto potenti possono essere le tue dita programmatrici.

Timbro

Timbro è solo un bella parola per descrivere il suono di un suono. Se, infatti, provi a suonare la stessa nota con strumenti differenti come, ad esempio, il violino, la chitarra, il pianoforte, il pitch (l’altezza della nota) sarà lo stesso ma la qualità sonora sarà diversa. Questa qualità sonora, quella che ti permette di distinguere un pianoforte da una chitarra è il timbro.

Composizioni melodiche

Un’altro aspetto importante per il nostro synth lead è la scelta delle note che vogliamo suonare. Se hai già un’idea a riguardo, puoi creare semplicemente un ring con le note e utilizzare il tick per scorrere da una all’altra:

live_loop :riff do
  use_synth :prophet
  riff = (ring :e3, :e3, :r, :g3, :r, :r, :r, :a3)
  play riff.tick, release: 0.5, cutoff: 80
  sleep 0.25
end

In questo esempio abbiamo definito la nostra melodia con un anello che include sia note come, ad esempio :e3 che pause rappresentate da :r. Usiamo .tick per scorrere tra le note e avere un riff che si ripete.

Melodia automatica

Spesso non è semplice trovare un buon riff partendo da zero. Spesso è più semplice chiedere a Sonic Pi una selezione di riff casuale per scegliere il migliore. Per fare una cosa del genere, abbiamo bisogno di tre cose: anelli, casualità e seme di casualità. Proviamo a vedere un esempio:

live_loop :random_riff do
  use_synth :dsaw
  use_random_seed 3
  notes = (scale :e3, :minor_pentatonic).shuffle
  play notes.tick, release: 0.25, cutoff: 80
  sleep 0.25
end

Qui succedono un po’ di cose… cerchiamo di andare con ordine. Per prima cosa specifichiamo che stiamo usando 3 come seme di casualità. Cosa significa? La cosa importante è sapere che quando utilizziamo un seme, possiamo fare una predizione su quello che sarà il prossimo numero casuale. Un’altro punto importante è che mescolare un anello di note funziona nello stesso modo. Nell’esempio qui sopra stiamo semplicemente chiedendo la il terzo mescolamento nella lista standard dei mescolamenti (che sarà sempre la stessa quando impostiamo lo stesso seme prima di mescolare). Infine utilizziamo il tick per scorrere tra le note per suonare il riff.

Qui comincia il bello. Se cambiamo il seme a, per esempio, 3000, otterremo un mescolamento completamente differente. Così diventa semplice esplorare nuove melodie:è sufficiente scegliere una lista di note che vogliamo mescolare (le scale sono un ottimo punto di partenza) e poi scegliere il seme con cui le vogliamo mescolare. Se non ci piace la melodia, basta cambiare una delle due cose e riprovare finché non sentiamo qualcosa che ci piace.

Pseudo casualità

La casualità in Sonic Pi non è realmente casuale ma è quello che si chiama pseudo-random. Immagina di lanciare un dado 100 volte e scrivere il risultato di ogni lancio su un foglio di carta. Sonic Pi ha lo stesso numero di possibili risultati quando gli chiediamo un numero casuale ma, invece che lanciare un dado, prendere il valore successivo in lista. Impostando un seme stabiliamo un punto specifico di inizio da quella lista.

Trovando il tuo ritmo

Un altro aspetto importante del riff è il ritmo ovvero quando suonare una nota e quando no. Come abbiamo visto in precedenza, possiamo usare :r nel nostro anello per aggiungere le pause. Un’altra possibilità è l’utilizzo degli spread che vedremo in futuro. Oggi continueremo a usare la casualità per trovare il nostro ritmo. Invece che suonare ogni nota, possiamo usare una condizione per far sì che suoni con una certa probabilità. Diamo un’occhiata:

live_loop :random_riff do
  use_synth :dsaw
  use_random_seed 30
  notes = (scale :e3, :minor_pentatonic).shuffle
  16.times do
    play notes.tick, release: 0.2, cutoff: 90 if one_in(2)
    sleep 0.125
  end
end

Una funzione molto utile da conoscere è one_in che restituisce il valore true o false con la probabilità specificata. Qui stiamo usando un valore 2 quindi one_in restituirà true una volta su due. In altre parole, il 50% delle volte avremo true. Utilizzando valori più alti, alzeremo le probabilità che ritorni false aumentando gli spazi nel riff.

Da notare che abbiamo usato l’iterazione 16.times. Questo perché vogliamo resettare il nostro valore di seme ogni 16 così per cui il nostro ritmo si ripeterà per 16 volte. Questo non ha effetti sul mescolamento perché viene eseguito immediatamente appena è impostato il seme. Possiamo modificare le quantità di ripetizioni nell’iterazione per allungare il riff. Prova a cambiare il valore da 16 a 8 oppure 4 o 3 per vedere come cambia il ritmo del riff.

Mettiamo tutto insieme

Ok, mettiamo insieme tutto quello che abbiamo imparato oggi in un ultimo esempio. Alla prossima!

live_loop :random_riff do
  #  togli il cancelletto che serve per i commenti per attivare la funzione:
  #  synth :blade, note: :e4, release: 4, cutoff: 100, amp: 1.5
  use_synth :dsaw
  use_random_seed 43
  notes = (scale :e3, :minor_pentatonic, num_octaves: 2).shuffle.take(8)
  8.times do
    play notes.tick, release: rand(0.5), cutoff: rrand(60, 130) if one_in(2)
    sleep 0.125
  end
end
 
live_loop :drums do
  use_random_seed 500
  16.times do
    sample :bd_haus, rate: 2, cutoff: 110 if rand < 0.35
    sleep 0.125
  end
end
 
live_loop :bd do
  sample :bd_haus, cutoff: 100, amp: 3
  sleep 0.5
end

- Acid Bass

È impossibile ripercorrere la storia della musica elettronica senza riscontrare l’impatto del piccolo sintetizzatore Roland TB-303. È l’ingrediente segreto alle spalle del suono acid bass. I riff creati con il TB-303 si sentono dai primi brani della scena House di Chicago fino ad artisti più recenti come Plastikman, Squarepusher e Aphex Twin.

La cosa interessante è che la Roland non aveva creato la TB-303 per la dance music. Originariamente era pensata come strumento di aiuto per i chitarristi: potevano programmare delle linee di basso per improvvisarci sopra. Purtroppo c’erano una serie di problemi: era difficile da programmare, non aveva dei suoni di basso convincenti e costava parecchio. Decisi a limitare le perdite, Roland ha chiuso la produzione a 10.000 unità vendute dopo aver passato molti anni sugli scaffali dei chitarristi. Presto, però, avrebbero avuto vita nuova nei negozi dell’usato. Quelle TB-303 aspettavano solo di essere riscoperte da una nuova generazione di sperimentatori che hanno cominciato a utilizzarle in modi diversi da quelli pensati da Roland per creare nuovi suoni. E così è nata l’Acid House.

Anche se non è così semplice mettere le mani su una TB-303 originale, puoi far si che il tuo Raspberry Pi ne diventi una grazie alla potenza di Sonic Pi. Apri il programma e scrivi questo codice e premi Run:

use_synth :tb303
play :e1

Acid bass istantaneo! Proviamo a smanettare un po’…

Modifichiamo quel basso

Per prima cosa, costruiamo un arpeggiatore. Nell’ultimo tutorial abbiamo visto come i riff possano essere semplicemente degli anelli di note suonate in sequenza e ripetute. Creiamo un live loop che faccia esattamente questo:

use_synth :tb303
live_loop :squelch do
  n = (ring :e1, :e2, :e3).tick
  play n, release: 0.125, cutoff: 100, res: 0.8, wave: 0
  sleep 0.125
end

Guarda ogni linea di codice.

Nella prima riga, impostiamo il sintetizzatore di default tb303 con la funzione use_synth. Nella seconda riga, creiamo un live loop chiamato :squelch che continua a ripetersi. La terza riga è dove creiamo il nostro riff: un anello di note (E dalla prima alla terza ottava) che suoniamo in ordine con .tick. Definiamo n affinché rappresenti la nota corrente del riff. Il simbolo di uguale significa: assegna il valore a destra al nome sulla sinistra. Questa sarà diversa ogni volta che il loop si ripete. La prima volta n sarà :e1, la seconda :e2 seguita da :e3 e poi dall’inizio. La quarta linea è dove effettivamente facciamo suonare il synth :tb303. Passiamo una serie di parametri interessanti: release:, cutoff:, res:, e wave: che discuteremo più avanti. La quinta linea è per la pausa sleep (stiamo chiedendo al nostro loop di ripetersi ogni 0.125 secondi o 8 volte al secondo a 60BPM). La sesta linea è la fine end del live loop. Questo dice a Sonic Pi dove finisce il live loop.

Anche se stai ancora cercando di capire che sta succedendo, scrivi il codice sopra e premi Run. Dovresti sentire il battito del ‘:tb303’ in azione. Quindi, ecco dove sta l’azione: cominciamo a fare live coding.

Anche se il loop è ancora attivo, cambia il valore di ‘cutoff:’ a ‘110’ e premi di nuovo Run. Dovresti sentire il suono divenare un po’ più ruvido e gracchiante. Digita ‘120’ e premi Run e poi ‘130’ e di nuovo Run. Ascolta i cambiamenti nel suono provocati da queste variazioni. Infine, prova a mettere un valore più basso, tipo ‘80’. Quindi poi ripeti questi cambiamenti con i numeri che vuoi e quante volte vuoi. Non preoccuparti, io ti aspetto qui…

Un’altra caratteristica con cui vale la pena giocare è ‘res:’. Questo parametro controlla la risonanza del filtro. Una risonanza alta è caratteristica dei suoni bassi un po’ acidi. Adesso abbiamo impostato questo parametro a ‘0.8’. Prova ad aumentarlo progressivamente a ‘0.85’. ‘0.90’, ‘0.95’. Se metti il valore di cutoff a ‘110’ o di più, le variazioni si percepiscono meglio. Infine, prova a fare una pazzia e metti ‘0.999’ come valore di risonanza. A valori così alti di risonanza, puoi sentire il filtro passa-alto, di cui imposti il valore di cutoff, che comincia a risuonare così tanto che si metterà a fare suoni esso stesso, senza che tu intervenga!

Infine, per avere variazioni significative del timbro, prova a cambiare ‘wave:’, ovvero forma d’onda, mettendo ‘1’. Questo parametro infatti ti permette di variare l’oscillatore che genera il suono. Quello preimpostato è ‘0’, cioè un generatore di onda a dente di sega. Il numero ‘1’ è un generatore di impulsi e infine ‘2’ è un generatore di onda triangolare.

Quindi, adesso puoi senz’altro provare differenti giri di note cambiando i suoni all’interno dell’anello o anche prendere note da scale o accordi. Divertiti con il tuo primo sintetizzatore di bassi acidi.

Decostruire il TB-303

Il progetto del TB-303 originale è piuttosto semplice. Compe potrai notare dal diagramma che segue, ci sono soltanto 4 parti principali.

TB-303 Design

Il primo è l’oscillatore d’onda, ovvero l’ingrediente base del suono. In questo caso noi abbiamo un oscillatore di onda quadra. Sussessivamente, abbiamo ampiezza dell’inviluppo dell’oscillatore, che controlla l’ampiezza dell’onda quadra nel tempo. Questa dimensione è accessibile da Sonic Pi mediante i parametri ‘attack:’, ‘decay:’, ‘sustain:’ e ‘release:’. Per maggiori informazioni, leggi la sezione 2.4 ‘Durata degli inviluppi’ all’interno della guida. Poi facciamo passare la nostra onda attraverso un filtro passa-basso. Questo taglia le frequenze più acute e dà al suono quella risonanza particolare. E qui comincia il bello. Infatti il valore di taglio (cutoff) del filtro è anche determinato dal suo stesso inviluppo! Questo significa che abbiamo un controllo straodinario sul timbro del suono se giochiamo con entrambi gli inviluppi. Dai un’occhiata sotto:

use_synth :tb303
with_fx :reverb, room: 1 do
  live_loop :space_scanner do
    play :e1, cutoff: 100, release: 7, attack: 1, cutoff_attack: 4, cutoff_release: 4
    sleep 8
  end
end

Per ogni opzione di inviluppo abbiamo un valore di taglio (cutoff) equivalente che possiamo impostare all’interno del synth ‘:tb303’. Quindi, per cambiare il tempo di attacco del valore di taglio possiamo usare il parametro ‘cutoff_attack:’. Copia il codice sopra e incollalo in una finestra vuota. Poi premi Run. Sentirai un suono impazzito che ribolle. Quindi, cominciamo adesso a suonare. Prova a cambiare il valore di ‘cutoff_attack:’ a ‘1’ e poi a ‘0.5’. Adesso prova ‘8’.

Come avrai visto, abbiamo fatto passare tutto il segnale attraverso un effetto di reverbero con ‘:reverb’, ottenendo una bella ambientazione sonora. Provane altri per vedere che succede!

Mettiamo tutto insieme

Infine, ecco qui un brano che ho composto usando le idee di questa guida. Copialo e incollalo dentro una finestra vuota, prova ad ascoltarlo per un po’ e poi comincia a fare i tuoi cambiamenti senza fermare il processo, facendo live coding. Ascolta i magnifici suoni che puoi produrre in questo modo! Ci vediamo la prossima volta…

use_synth :tb303
use_debug false
 
with_fx :reverb, room: 0.8 do
  live_loop :space_scanner do
    with_fx :slicer, phase: 0.25, amp: 1.5 do
      co = (line 70, 130, steps: 8).tick
      play :e1, cutoff: co, release: 7, attack: 1, cutoff_attack: 4, cutoff_release: 4
      sleep 8
    end
  end
 
  live_loop :squelch do
    use_random_seed 3000
    16.times do
      n = (ring :e1, :e2, :e3).tick
      play n, release: 0.125, cutoff: rrand(70, 130), res: 0.9, wave: 1, amp: 0.8
      sleep 0.125
    end
  end
end

- Minecraft Musicale

Ciao, bentornato/a! Nella guida precedente ci siamo concentrati maggiormente sulle possibilità musicali di Sonic Pi, ovvero far diventare il tuo Raspberry Pi uno strumento musicale pronto all’uso. Fino ad ora, abbiamo imparato a:

Fare live coding: cambiare i suoni in tempo reale, Scrivere codice per produrre dei bei bassi che pompano, Generare delle potenti linee melodiche con i synth, Ricreare il suono acido e basso del TB-303.

C’è anche molto altro che vorrei mostrarti e che tratteremo in edizioni future di questa guida. Comunque, questo mese, diamo un’occhiata a qualcosa che Sonic Pi può fare e della quale probabilmente non sei a conoscenza: controllare Minecraft.

Ciao mondo di Minecraft

Bene, cominciamo allora. Accendi il tuo Raspberry Pi e avvia il tuo Minecraft Pi creando un nuovo mondo. Quando hai fatto, avvia Sonic Pi, ridimensiona e sposta la finestra in modo tale da riuscire a vedere le due finestre contemporaneamente.

In una finestra vuota di Sonic Pi inserisci il codice seguente:

mc_message "Hello Minecraft from Sonic Pi!"

Adesso premi Run. Booom! Il tuo messaggio è apparso dentro Minecraft! E’ stato facile, vero? Adesso, smetti per un momento di leggere e mettiti a giocare scrivendo alcuni messaggi a tuo piacimento. Goditela!

Screen 0

Teletrasporto sonico

Adesso, mettiamoci un attimo a esplorare. Solitamente utilizziamo il mouse e la tastiera per camminare in giro. Funziona, è vero, ma è piuttosto lento e noioso. Sarebbe molto meglio avere una sorta di macchina del teletrasporto. Beh, grazie a Sonic Pi, ce l’abbiamo. Prova il codice seguente:

mc_teleport 80, 40, 100

Perbacco! Era una strada lunga. Se non fossi stato in modalità volante saresti ricaduto giù a terra. Se tocchi due volte lo spazio per entrare in modalità volo e teletrasportarti di nuovo, rimarrai a fluttuare nel posto che hai toccato.

Allora, cosa significano quei numeri? Abbiamo tre numeri che descrivono le coordinate del posto nel mondo in cui vogliamo andare. Diamo a ogni numero un nome: x, y e z:

x indica quanto ci spostiamo a destra o sinistra (80 nel nostro esempio) y indica quando in alto vogliamo rimanere (40 nel nostro esempio) z indica quanto vogliamo andare avanti o indietro (100 nel nostro esempio)

Scegliendo differenti valori per x, y e z possiamo teletrasportarci ovunque nel nostro mondo. Prova! Scegli dei numeri diversi e guarda dove vai a finire. Se lo schermo diventa nero è perché ti sei teletrasportato/a sotto terra o in una montagna. Scegli un numero di y più alto e vedrai che tornerai in superficie. Continua a esplorare finché non trovi un posto che ti piace…

Usa le idee spiegate fino a ora e costruisci un Teletrasporto Sonico che rende divertente spostare dei suoni mentre ci spara in giro nel mondo di Minecraft:

mc_message "Preparing to teleport...."
sample :ambi_lunar_land, rate: -1
sleep 1
mc_message "3"
sleep 1
mc_message "2"
sleep 1
mc_message "1"
sleep 1
mc_teleport 90, 20, 10
mc_message "Whoooosh!"

Screen 1

Blocchi magici

Adesso che hai finalmente trovato un posto bello, comincia a costruire. Puoi fare quello che fai di solito e cominciare a cliccare il mouse furiosamente per mettere i blocchi sotto il cursore. Oppure, puoi utilizzare la magia di Sonic Pi. Prova questo codice:

x, y, z = mc_location
mc_set_block :melon, x, y + 5, z

Guarda in alto! C’è un melone nel cielo! Guarda un attimo il codice. Che cosa abbiamo fatto? Nella prima riga abbiamo preso la posizione attuale di Steve e codificata come variable di x, y e z. Queste lettere corrispondono alle coordinate descritte in precedenza. Abbiamo usato queste coordianate nella funzione ‘mc_set_block’ che pone il blocco scelto nel luogo indicato dalle coordinate. Per porre qualcosa nel cielo, dobbiamo soltanto incrementare il valore di y. E’ per questo che abbiamo aggiunto 5. Proviamo a fare una lunga striscia di meloni:

live_loop :melon_trail do
  x, y, z = mc_location
  mc_set_block :melon, x, y-1, z
  sleep 0.125
end

Quindi, torniamo a Minecraft, assicurati di essere in modalità volo (tocca due volte spazio se non lo sei) e vola intorno al mondo. Guarda in giù e vedrai una bellissima scia di meloni. Guarda che belle figure intrecciate che puoi fare nel cielo.

Fare live coding con Minecraft

Coloro che hanno seguito questa guida durante gli ultimi mesi avranno probabilmente la mente già aperta. La scia di meloni è molto bella, ma la parte più interessante dell’esempio precedente è il poter fare un ‘live_loop’ con Minecraft! Per chi non lo sapesse, ‘live_loop’ è un’abilità magica di Sonic Pi che nessun altro linguaggio di programmazione ha. Ti permette di far girare numerosi loop contemporaneamente e di cambiarli mentre sono in esecuzione. Sono incredibilmente potenti e fonte di estremo divertimento. Io uso i ‘live_loop’ per suonare musica nei locali con Sonic Pi; i DJ usano i dischi e io uso i ‘live_loop’ :-). Comunque, oggi andremo a programmare dal vivo sia la musica sia Minecraft.

Iniziamo. Esegui il codice sopra e inizia nuovamente a costruire la tua scia di meloni. Adesso, senza fermare l’esecuzione, cambia ‘:melon’ con ‘:brick’ (mattone) e premi Run. Bravo! Adesso stai facendo una scia di mattoni. Semplice no?! Vuoi aggiungere anche un po’ di musica? Facile, prova questo:

live_loop :bass_trail do
  tick
  x, y, z = mc_location
  b = (ring :melon, :brick, :glass).look
  mc_set_block b, x, y -1, z
  note = (ring :e1, :e2, :e3).look
  use_synth :tb303
  play note, release: 0.1, cutoff: 70
  sleep 0.125
end

Ora, mentre la musica sta suonando, tu comincia a cambiare il codice. Cambia i tipi di blocco: prova ‘:water’, ‘:grass’ o la tua categoria di blocchi preferita. Cambia anche il valore ‘cutoff:’ da ‘70’ a ‘80’ e successivamente anche a ‘100’. Non è divertente?

Mettiamo tutto insieme

Screen 2

Combiniamo tutto quello che abbiamo visto finora aggiungendo un tocco di ulteriore magia. Associamo la nostra abilità di teletrasportarci, il posizionamento dei blocchi e la musica per fare una sorta di video musicale di Minecraft. Non ti preoccupare se non riesci a capire tutto. Digita soltanto il testo e divertiti cambiando alcuni valori mentre il codice è in esecuzione. Divertiti e ci vediamo la prossima volta…

live_loop :note_blocks do
  mc_message "This is Sonic Minecraft"
  with_fx :reverb do
    with_fx :echo, phase: 0.125, reps: 32 do
      tick
      x = (range 30, 90, step: 0.1).look
      y = 20
      z = -10
      mc_teleport x, y, z
      ns = (scale :e3, :minor_pentatonic)
      n = ns.shuffle.choose
      bs = (knit :glass, 3, :sand, 1)
      b = bs.look
      synth :beep, note: n, release: 0.1
      mc_set_block b, x+20, n-60+y, z+10
      mc_set_block b, x+20, n-60+y, z-10
      sleep 0.25
    end
  end
end
live_loop :beats do
  sample :bd_haus, cutoff: 100
  sleep 0.5
end

- Battiti di Bizet

Dopo la nostra breve trattazione del fantastico mondo del controllo di Minecraft attraverso Sonic Pi dello scorso mese, ricominciamo a fare musica. Oggi, ci occuperemo di creare un fantastico pezzo dance del 21° secolo usando le meravigliose proprietà del codice.

Oltraggioso e distruttivo

Torniamo indetro al 1875. Un compositore chiamato Bizet aveva appena terminato la sua ultima opera, Carmen. Sfortunatamente, come molti pezzi che rompevano gli schemi preesistenti, le persone non apprezzarono questa opera perché fu considerata oltraggiosa e troppo fuori dai canoni. Purtroppo, Bizet morì dieci anni prima di vedere il suo lavoro salire al successo internazionale, diventando una delle opere più famose ed eseguite della storia della musica. Per onorare questa tragedia, prendiamo una delle melodie più famose della Carmen e rivisitiamola in chiave moderna rendendola anche noi oltraggiosa e differente dai canoni prestabiliti a noi contemporanei. La suoneremo attraverso il live coding!

Decodificare la Habanera

Suonare con il live coding l’intera opera sarebbe una cosa un po’ difficile da far entrare in questa guida, quindi focalizziamoci soltanto sulle parti più famose. In questo caso, prendiamo la linea di basso dell’Habanera:

Habanera Riff

Questa cosa potrebbe sembrare particolarmente difficile da leggere se non hai studiato la notazione musicale. Tuttavia, noi programmatori consideriamo la notazione musicale come una forma diversa di codice. Infatti essa rappresenta delle istruzioni destinate a un musicista invece che a un computer. Quindi, dobbiamo solo capire come riuscire a decodificarla.

Note

Le note sono organizzate da destra a sinistra, in modo simile alle parole di questa rivista. Però, esse hanno anche differenti altezze. La posizione verticale della nota rappresenta anche quanto essa è acuta o grave. Più è posta in alto nel pentagramma, più la nota sarà acuta.

Abbiamo già visto come cambiare l’altezza di una nota in Sonic Pi. Possiamo usare sia numeri più o meno alti come ‘play 75’ o ‘play 80’, sia i nomi delle note in notazione alfabetica come ‘play :E’ e ‘play :F’ (ovvero suona Mi e suona Fa in notazione italiana). Fortunatamente, ogni posizione della nota nella partitura rappresenta il nome di una specifica nota. Dai un’occhiata a questa tabella:

Notes

Pause

La partitura musicale è un tipo di codice molto ricco ed espressivo, capace di comunicare molte cose. Non dovrebbe essere troppo soprendente quindi scoprire che essa non solo ti dice quale nota suonare ma anche quando non devi suonarne. Nei linguaggi di programmazione, questo aspetto somiglia all’idea di ‘nil’ o ‘null’, ovvero l’assenza di un valore. In altre parole, non suonare una nota significa l’assenza di una nota.

Se guardi attentamente la partitura, ti accorgerai che è formata da una combinazione di punti neri dotati di linee che rappresentano la nota da suonare e delle cose strambe che rappresentano le pause. Fortunatamente, Sonic Pi ha una rappresentazione molto pratica delle pause: ‘:r’. Quindi se eseguiamo l’istruzione ‘plat :r’, Sonic Pi suonerà il silenzio! Possiamo anche scrivere ‘play :rest’, ‘play nil’ o ‘play false’, che sono tutti equivalenti alla prima.

Ritmo

Infine c’è un’ultima cosa da imparare: come decodificare la notazione ovvero il timing delle note. Nella notazione originale, puoi vedere che le note sono connesse da linee spesse chiamate codette (o stanghette). La seconda nota ha due stanghette quindi dura 1/16. Le altre note hanno una singola stanghetta che indica una durata di 1/8. La pausa ha anch’essa due stanghette infatti ha una durata di 1/16.

Quando proviamo a decodificare o esplorare nuove cose, un trucco è rendere tutto il più simile possibile per vedere eventuali relazioni o pattern. Per esempio, quando riscriviamo tutto con note da 1/16 puoi notare come la notazione diventi una bella sequenza di note e pause.

Habanera Riff 2

Programmare l’Habanera

Stiamo per tradurre questa linea di basso in Sonic Pi. Codifichiamo queste note e pause in un anello:

(ring :d, :r, :r, :a, :f5, :r, :a, :r)

Proviamo a sentire come suona. Inseriamo tutto in un live loop con un tick per scorrere:

live_loop :habanera do
  play (ring :d, :r, :r, :a, :f5, :r, :a, :r).tick
  sleep 0.25
end

Fantastico, il riff che suona dalle casse è istantaneamente riconoscibile. È stato molto faticoso arrivare fino a qui ma ne valeva la pena. Batti un cinque!

Synth malinconico

Ora che abbiamo la linea di basso, ricreiamo l’ambientazione della scene lirica. Un synth da provare è :blade che è un sintetizzatore malinconico degli anni ‘80. Proviamolo facendo passare la nota iniziale :d attraverso uno slicer e un riverbero:

live_loop :habanera do
  use_synth :fm
  use_transpose -12
  play (ring :d, :r, :r, :a, :f5, :r, :a, :r).tick
  sleep 0.25
end
with_fx :reverb do
  live_loop :space_light do
    with_fx :slicer, phase: 0.25 do
      synth :blade, note: :d, release: 8, cutoff: 100, amp: 2
    end
    sleep 8
  end
end

Ora, proviamo con le altre note nella linea di basso: :a e :f5. Ricorda: non devi premere stop, puoi modificare il codice mentre la musica sta suonando e premere Run di nuovo. Prova anche a cambiare i valori (ad esempio 0.5, 0.75 e 1) del parametro phase: dello slicer.

Mettiamo tutto insieme

Infine, combiniamo tutte le idee che abbiamo avuto fino ad ora per un remix dell’Habanera. Come puoi notare, ho aggiunto un’altra linea di basso come un commento. Una volta scritto tutto in un buffer vuoto, premi Run e senti come suona la composizione. Ora, senza premere stop togli il commento dalla seconda linea rimuovendo il # e poi premi di nuovo Run. Quando è figo? Ora prova a fare un po’ di cambiamenti e divertiti.

use_debug false
bizet_bass = (ring :d, :r, :r, :a, :f5, :r, :a, :r)
#bizet_bass = (ring :d, :r, :r, :Bb, :g5, :r, :Bb, :r)
 
with_fx :reverb, room: 1, mix: 0.3 do
  live_loop :bizet do
    with_fx :slicer, phase: 0.125 do
      synth :blade, note: :d4, release: 8,
        cutoff: 100, amp: 1.5
    end
    16.times do
      tick
      play bizet_bass.look, release: 0.1
      play bizet_bass.look - 12, release: 0.3
      sleep 0.125
    end
  end
end
 
live_loop :ind do
  sample :loop_industrial, beat_stretch: 1,
    cutoff: 100, rate: 1
  sleep 1
end
 
live_loop :drums do
  sample :bd_haus, cutoff: 110
  synth :beep, note: 49, attack: 0,
    release: 0.1
  sleep 0.5
end

- Diventa un DJ di Minecraft

Screen 0

Tutti abbiamo giocato a Minecraft. Probabilmente avrai costruito strutture grandiose, disegnato trappole e creato linee di carrelli elaborate attraverso gli switch. Ma quanti di voi si sono esibiti con Minecraft? Scommetto che non sapevate di poter usare Minecraft per creare visual incredibili come un VJ professionista.

Se l’unico modo di modificare Minecraft fosse il mouse, faresti molta fatica a cambiare le cose velocemente. Per fortuna, il tuo Raspberry Pi ha una versione di Minecraft che può essere controllare con il codice. E c’è anche un’app chiamata Sonic Pi che rende programmare Minecraft facile e divertente.

Nell’articolo di oggi, ti mostrerò qualche trucchetto che abbiamo usato per esibirci in night club e locali in giro per il mondo.

Cominciamo…

Cominciamo

Partiamo da un semplice esercizio di riscaldamento per ricordarci le basi. Per prima cosa, apri sul tuo Raspberry Pi sia Minecraft che Sonic Pi. In Minecraft crea un nuovo mondo e in Sonic Pi scegli un buffer vuoto e incolla questo codice:

mc_message "Let's get started..."

Premi Run e vedrai un messaggio nella finestra di Minecraft. Ok, siamo pronti per partire e divertici…

Tempesta di sabbia

Quando usiamo Minecraft per creare visual, dobbiamo pensare a qualcosa che sia interessante da vedere e semplice da generare. Un semplice trucco è creare una tempesta di sabbia facendo cadere blocchi di sabbia dal cielo. Per farlo, abbiamo bisogno di semplici funzioni:

sleep - per inserire una pausa tra le azioni mc_location - per trovare la nostra posizione attuale mc_set_block- per piazzare blocchi di sabbia in una posizione specifica rrand - per generare valori casuali all’interno di un range live_loop - per avere una continua pioggia di sabbia

Se non sei a conoscenza di qualcuna di queste funzioni come, ad esempio, rrand, scrivi la parola nel buffer, fai click su di essa e poi premi Control-i per aprire la documentazione relativa. In alternativa puoi accedere alla tab lang nell’aiuto e cercare direttamente la funzione.

Proviamo con un po’ di pioggia prima di fare una vera tempesta. Otteniamo la posizione correte per creare qualche blocco di sabbia nel cielo:

x, y, z = mc_location
mc_set_block :sand, x, y + 20, z + 5
sleep 2
mc_set_block :sand, x, y + 20, z + 6
sleep 2
mc_set_block :sand, x, y + 20, z + 7
sleep 2
mc_set_block :sand, x, y + 20, z + 8

Quando premi Run prova a guardarti intorno perché i blocchi potrebbero scendere dietro di te in base a dove stai guardando. Non ti preoccupare, se te li sei persi, premi Run di nuovo… basta essere sicuri di guardare nella giusta direzione!

Analizziamo velocemente cosa sta succedendo. Nella prima linea abbiamo preso la posizione di Steve come coordinate per la funzione mc_location e le abbiamo inserite nelle variabili x, y, e z. Poi, nella riga successiva, abbiamo usato mc_set_block per piazzare un po’ di sabbia nelle stesse coordinate con una leggera modifica: abbiamo scelto la stessa x mentre y e z con valori di 20 blocchi maggiori per far si che i blocchi di sabbia cadessero in linea lontano da Steve.

Perché non provi a modificare un po’ questo codice? Aggiungi un po’ di righe, cambia i tempi di pausa, prova a modificare :sand con :gravel e scegli coordinate different. Sperimenta e divertiti!

Liberiamo il Live Loop

Ok, è tempo di fare un vera e propria tempesta utilizzando la potenza di live_loop, una delle funzioni magiche di Sonic Pi che ci permette di esplorare tutta la potenza del live coding: modificare il codice mentre sta funzionando!

live_loop :sand_storm do
  x, y, z = mc_location
  xd = rrand(-10, 10)
  zd = rrand(-10, 10)
  co = rrand(70, 130)
  synth :cnoise, attack: 0, release: 0.125, cutoff: co
  mc_set_block :sand, x + xd, y+20, z+zd
  sleep 0.125
end

Che divertimento! Stiamo ripetendo tutto abbastanza velocemente (8 volte al secondo) e ad ogni loop cerchiamo la posizione di Steve ma stavolta generiamo 3 valori casuali:

‘xd’ - quando x è tra -10 e 10 ‘zd’ - quando anche z è tra -10 e 10 ‘co’ - è un valore di taglio di un filtro passabasso e può stare tra 70 e 130

Quindi usiamo quei valori casuali nelle funzioni ‘synth’ e ‘mc_set_block’ per creare della sabbia che cade in luoghi casuali intorno a Steve insieme a un suono percussivo di pioggia prodotto dal synth ‘:cnoise’.

Per quelli e quelle che ancora non conoscono i live loop, posso dirvi che è proprio qui che ci si comincia a divertire con Sonic Pi. Mentre il codice è in esecuzione e la sabbia sta cadendo, prova a cambiare uno dei valori, magari il tempo di sleep a ‘0.25’ oppure la tipologia di blocco da ‘:sand’ a ‘:gravel’. Premi di nuovo Run. Hey, facile! Le cose sono cambiate senza arrestare l’esecuzione. Questo è il tuo primo passo nella carriera di VJ! Continua a fare pratica e a cambiare le cose. Quanto puoi cambiare le immagini senza arrestare l’esecuzione del codice?

Combinazioni di blocchi epiche

Screen 1

Infine, un altro modo molto divertente di generare delle immagini interessanti è di creare enormi muri con diverse combinazioni di blocchi sopra cui volare e avvicinarsi. Per creare questo effetto, dobbiamo smettere di posizionare i blocchi casualmente, mettendoli invece in maniera ordinata. Possiamo farlo intrecciando due gruppi di iterazioni diverse (premi il tasto Help e vai alla sezione 5.2, “Iterazione e loop” per maggiori informazioni sull’iterazione). Il valore ‘ xd ’ posizionato dopo il ‘do’ significa che ‘xd’ sarà il valore stabilito per ogni iterazione. Quindi, la prima volta sarà 0, poi 1, 2 e così via. Intrecciando due iterazioni tra loro in questo modo possiamo generare tutte le coordinate di un quadrato. Così, poi possiamo scegliere casualmente i tipi di blocco per creare degli effetti interessanti:
x, y, z = mc_location
bs = (ring :gold, :diamond, :glass)
10.times do |xd|
  10.times do |yd|
    mc_set_block bs.choose, x + xd, y + yd, z
  end
end

Abbastanza chiaro. Mentre ci divertiamo qui, proviamo a cambiare ‘bs.choose’ con ‘bs.tick’ per spostarci da uno schema casuale a uno più regolare. Prova a cambiare anche il tipo di blocco e i più coraggiosi possono anche provare a includere tutto in un ‘live_loop’ così che la struttura continuerà a cambiare automaticamente.

Quindi, per un gran finale da VJ, cambia i due ‘10.times’ con ‘100.times’ e premi Run. Booom! Un muro gigantesco di blocchi posti casualmente! Immaginati quando tempo potresti impiegare a costruire una cosa del genere usando solo il mouse! Premi due volte lo spazio per entrare in modalità volante e comincia a sorvolare tutto per creare un fantastico effetto visivo. Non fermarti qui, usa la tua immaginazione per dar forma alle tue idee e poi utilizza il potere del codice di Sonic Pi per realizzarle. Quando avrai fatto pratica a sufficienza, abbassa le luci e organizza uno spettacolo visuale per i tuoi amici!


- Scivolare su correnti casuali

Tornando indietro all’episodio 4 di questo tutorial, avevamo dato un breve sguardo alla randomizzazione mentre programmavamo alcuni riff di synth. Considerando che la randomizzazione è una parte importante della mia pratica musicale live code DJ, ho pensato che fosse utile di trattare i fondamentali di questo aspetto più nel dettaglio. Quindi, mettiti comodo e partiamo sulle strade della randomizzazione!

Il caso non esiste

La prima cosa da imparare, e che potrebbe sorprenderti quando suoni le funzioni random di Sonic PI, è che in realtà esse non sono davvero casuali. Che significa questo? Proviamo a fare un paio di prove. Primo: prova a pensare un numero tra 0 e 1. Tienitelo in mente e non dirmelo. Provo a indovinare…Era ‘0.321567’? No? Bah, non sono molto bravo allora. Fammi fare un altro tentativo, ma stavolta fai scegliere il numero a Sonic Pi. Avvia il programma e chiedigli un numero casuale; ma anche stavolta non dirmelo:

print rand (stampa i numeri casuali)

Quindi riproviamoci…era 0.75006103515625? Sì! Riesco a vedere il tuo scetticismo. Forse era solo fortuna. Riproviamo. Premi di nuovo Run e vediamo che cosa esce…Cosa, 0.75006103515625 di nuovo? Questo non può essere sicuramente casuale! Sì, hai ragione, non lo è.

Che sta succedendo? La parola usata in informatica è determinismo. Questo significa che niente è casuale e tutto è destinato a esserlo. La tua versione di Sonic Pi è destinata sempre a restituire il numero 0.75006103515625 se esegui il programma scritto sopra. Questo potrebbe sembrarti piuttosto inutile, ma ti assicuro che invece è uno degli aspetti più utili di Sonic Pi. Se ti applichi un po’ imparerai come rapportarti alla natura deterministica della randomizzazione di Sonic Pi e capirai che questo aspetto è fondamentale per le tue composizioni e le tue performance da DJ.

Una melodia casuale

Quando Sonic Pi si avvia, in realtà carica nella memoria una sequenza di 441000 valori casuali già generati. Quando richiami una funzione che genera casualità, come ‘rand’ o ‘rrand’, questo flusso casuale è usato per generare il tuo risultato. Ogni richiamo di una funzione di questo tipo prende i valori da questo flusso. Quindi la decima chiamata di una funzione random userà il decimo valore di quel flusso. Inoltre, ogni volta che premi Run, il flusso riparte da zero. Questo è il motivo per cui sono riuscito a predire il risultato prima ed è anche il motivo per cui una melodia ‘casuale’ è sempre uguale ogni volta. Ogni versione di Sonic Pi usa lo stesso flusso di valori casuali. Questo è molto importante quando cominciamo a condividere i nostri brani musicali tra noi.

Usiamo quanto appena imparato per generare una melodia casuale ripetibile:

8.times do
 play rrand_i(50, 95)
 sleep 0.125
end

Digita il codice sopra in una finestra vuota e premi Run. Ascolterai una melodia di note ‘casuali’ incluse tra 50 e 95. Quando è terminata, premi di nuovo Run e sentirai esattamente la stessa melodia.

Funzioni utili di randomizzazione

Sonic Pi viene fornito con una serie di funzioni utili per lavorare con il flusso di dati casuali. Eccoti una lista di alcune delle migliori:

‘rand’ - Semplicemente restituisce il prossimo valore del flusso di numeri casuali ‘rrand’ - Restituisce un valore casuale all’interno di due valori predeterminati ‘rrand_i’ - Restituisce un numero intero casuale all’interno di un intervallo predeterminato ‘one_in’ - è vero o falso secondo una casualità predeterminata ‘dice’ - imita il comportamento di un dado e quindi restituisce valori casuali tra 1 e 6 ‘choose’ - sceglie valori casuali da una lista

Dai un’occhiata alla loro documentazione nella sezione Help se vuoi maggiori informazioni o degli esempi.

Azzerare il flusso

L’abilità di ripetere una sequenza di note predeterminate è essenziale per riprodurre un riff mentre suoni. Tuttavia, quello che senti potrebbe non essere esattamente il riff a cui avevi pensato. Non sarebbe bello poter provare alcuni differenti riff e scegliere quello preferito? Qui è dove la magia ha inizio.

Possiamo regolare il flusso usando la funzione ‘use_random_seed’. In informatica, un random seed, ovvero un generatore di numeri casuali, ha un punto di inizio dal quale il flusso di valori causali parte. Prova quanto segue:

use_random_seed 0
3.times do
  play rrand_i(50, 95)
  sleep 0.125
end

Bene! Abbiamo ottenuto le prime tre note della nostra melodia casuale: ‘84’, ‘83’ e ‘71. Tuttavia, se vogliamo possiamo cambiare questa serie. Prova a eseguire questo:

use_random_seed 1
3.times do
  play rrand_i(50, 95)
  sleep 0.125
end

Interessante, abbiamo ottenuto ‘83’, ‘71’ e ‘61’. Forse noterai che le prime due cifre di questa serie sono le stesse delle ultime due appartenenti alla serie precedente. E non è una coincidenza.

Ricordati che il flusso di dati casuali è semplicemente una lista gigante di valori già predeterminati. Eseguendo ‘use_random_seed’ scegliamo da dove partire. Un’altra immagine che può renderti l’idea è un enorme mazzo di carte già mischiato. Usando questa funzione, noi scegliamo dove tagliare il mazzo. La cosa eccitante di questa funzione è proprio la sua abilità di saltare al punto del flusso che vogliamo, dandoci infinite possibilità musicali.

Riguardiamo brevemente la nostra melodia casuale di 8 note implementando questa funzione. Prima però inserisci il codice all’interno di un live loop, così possiamo effettuare modifiche mentre la melodia continua a suonare:

live_loop :random_riff do    
  use_random_seed 0
  8.times do
    play rrand_i(50, 95), release: 0.1
    sleep 0.125
  end
end

Adesso, mentre sta ancora suonando, cambia il valore della funzione da ‘0’ a qualcos’altro. Prova ‘100’ oppire ‘999’. Prova anche valori a tua scelta, sperimenta e divertiti. Valuta qual’è il riff che ti piace di più.

Mettiamo tutto insieme

Il tutorial di questo mese è stato un bel tuffo nelle funzioni di casualità utilizzabili in Sonic Pi. Spero di essere riuscito a darvi un’idea di come funziona e di aver suggerito un punto di partenza per usare la casualità in modo affidabile per creare pattern ripetitivi nella tua musica. È importante ribadire che puoi usare questa casualità ripetute dovunque tu voglia. Per esempio lo puoi fare per il volume delle note, il tempo di un ritmo, la quantità di riverbero, il synth corrente, il mix di un effetto ecc… In futuro vedremo alcune di queste applicazioni in dettaglio ma, per oggi, vi lascio con un piccolo esempio.

Scrivi il seguente codice in un buffer vuoto, premi Run e prova a cambiare il valore di seed. Premi Run di nuovo (mentre sta andando) e esplora le differenze sonore, di ritmo e di melodia che riesci a fare. Quando ne trovi una bella, ricordati del numero di seed per poterla risuonare. Infine, quando hai trovato un secondo valore di seed che produce risultati interessanti, fai una performance per i tuoi amici cambiando semplicemente tra un valore di seed e l’altro.

live_loop :random_riff do
  use_random_seed 10300
  use_synth :prophet
  s = [0.125, 0.25, 0.5].choose
  8.times do
    r = [0.125, 0.25, 1, 2].choose
    n = (scale :e3, :minor).choose
    co = rrand(30, 100)
    play n, release: r, cutoff: co
    sleep s
  end
end
live_loop :drums do
  use_random_seed 2001
  16.times do
    r = rrand(0.5, 10)
    sample :drum_bass_hard, rate: r, amp: rand
    sleep 0.125
  end
end

- Controllare il tuo suono

Fino ad ora ci siamo concentrati su come far partire suoni. Abbiamo scoperto che possiamo usare i synth inclusi in Sonic Pi utilizzando play o synth e come far suonare suoni pre-registrati con sample. Abbiamo anche imparato come aggiungere degli effetti a questi suoni come, ad esempio, il riverbero, utilizzando il comando with_fx. Combinando tutte queste cose con la gestione del tempo di Sonic Pi, puoi produrre una grande quantità di suoni, beat e riff. Però, una volta lanciata un’opzione di un suono, non c’è modo di controllarla, giusto? Sbagliato! Oggi impareremo qualcosa di molto importante: come controllare i synth mentre suonano.

Un suono semplice

Creiamo un suono semplice. Apri Sonic Pi e scrivi questo codice:

synth :prophet, note: :e1, release: 8, cutoff: 100

Ora premi il pulsante Run in alto a sinistra per ascoltare il suono. Ok, premilo un altro paio di volte per sentire come suona. Fatto? Bene, ora cominciamo a controllarlo!

Nodi dei synth

Una cosa di Sonic Pi che conoscono in pochi è che le funzioni play, synth e sample restituiscono una cosa chiamata SynthNode che rappresenta un suono riprodotto. È possibile controllare questi SynthNode usando una variabile e poi controllarla successivamente. Proviamo a cambiare il valore di cutoff: dopo 1 beat:

sn = synth :prophet, note: :e1, release: 8, cutoff: 100
sleep 1
control sn, cutoff: 130

Guardiamo ogni linea di codice:

Per prima cosa abbiamo suonato il synth :prophet utilizzando la normale funzione synth. Abbiamo, però, catturato il risultato in una variable chiamata sn. Avremmo potuto usare qualsiasi nome come, ad esempio, synth_note, o jane. Non avrebbe fatto differenza. È importante, però, scegliere nomi che abbiano un senso per la performance e per le persone che leggono il tuo codice. Io ho scelto sn perché è diminutivo facile da ricordare per synth node.

Nella seconda linea abbiamo un comando sleep normalissimo; non fa nulla di speciale se non dire al computer di aspettare 1 beat prima di andare avanti.

La linea 3 è dove comincia il divertimento. Ora usiamo la funzione control per dire al nostro SynthNode di cambiare il valore di cutoff a 130. Se premi Run sentirai il :prophet suonare come prima ma, dopo 1 beat, il suono diventerà molto più chiaro.

Opzioni modulabili

La maggior parte dei valori dei synth e degli effetti di Sonic Pi possono essere cambiati. Non è così per tutto, però. Per esempio i valori di inviluppo: attack:, decay:, sustain: e release: possono essere impostati prima dell’avvio del synth. Capire quali opzioni è possibile cambiare in corso d’opera è semplice, controlla nella documentazione per cercare la frase: “Può cambiare mentre sta suonando” oppure “Non può essere cambiato una volta impostato”. Per esempio guardando la documentazione relativa al parametro attack: del synth :beep dice chiaramente che non può essere modificato:

Default: 0 Deve essere più grande di 0 Non può essere modificato una volta impostato Scalato con il valore BPM corrente

Cambi multipli

Finché un synth sta suonando, non sei limitato al cambiarlo una volta sola; puoi farlo quante volte vuoi. Per esempio possiamo trasformare il nostro :prophet in un piccolo arpeggiatore così:

notes = (scale :e3, :minor_pentatonic)
sn = synth :prophet, note: :e1, release: 8, cutoff: 100
sleep 1
16.times do
  control sn, note: notes.tick
  sleep 0.125
end

In questo codice, abbiamo aggiunto un paio di cose in più. Per prima cosa abbiamo una variabile chiamata notes che contiene le note che vogliamo riprodurre (arpeggiatore è il nome carino che viene dato a qualcosa che suona delle note in ciclo). Seconda cosa: rimpiazziamo la nostra chiamata a control con un’interazione di 16 volte. In ogni chiamata a control usiamo .tickper il nostro anello di notes che si ripeterà automaticamente. Per un po’ di varietà, prova a sostituire .tick con .choose e vedi se senti la differenza.

Ora che puoi controllare più parametri simultaneamente, prova a cambiare la linea di controllo con questo codice:

control sn, note: notes.tick, cutoff: rrand(70, 130)

Sliding

Quando controlliamo un SynthNode, risponde esattamente a tempo cambiando immediatamente il valore di un parametro come se avessi premuto un bottone. Questo può dare un suono percussivo, specialmente se il parametro controlla un aspetto del timbro come il cutoff:. Tuttavia a volte non vuoi che il cambiamento sia istantaneo; a volte vorresti che fosse graduale, come utilizzando uno slider. Ovviamente Sonic Pi ti permette di farlo usando il parametro _slide:.

Ogni parametro che può essere modificato ha un corrispondente con _slide: che permette di impostare un tempo. Per esempio amp: ha amp_slide: e cutoff: ha cutoff_slide:. Questi parametri funzionano in modo leggermente diverso dagli altri perché dicono al synth come comportarsi la volta successiva che vengono controllati. Diamo un’occhiata:

sn = synth :prophet, note: :e1, release: 8, cutoff: 70, cutoff_slide: 2
sleep 1
control sn, cutoff: 130

Nota come questo esempio sia esattamente come lo stesso di prima con la sola aggiunta di cutoff_slide:. Questo significa che quando modificheremo il parametro cutoff: impiegherà 2 secondi per andare dal valore attuale al successivo. Possiamo usare control per sentire lo slide tra 70 e 130. Questo crea una dinamica interessante del suono. Ora prova a cambiare il valore cutoff_slide: su un intervallo di tempo più breve come 0.5 oppure più lungo come 4 e vedi come cambia il suono. Ricorda che puoi usare slide per ogni parametro modificabile e ciascuno _slide: può avere parametri differenti per cui puoi avere un cutoff lento e un amp veloce e un pan che sta tra i due.

Mettiamo tutto insieme

Proviamo a guardare a un breve esempio che dimostra la potenza del controllo dei synth. Nota come puoi controllare anche gli effetti cambiando leggermente la sintassi. Rileggiti la sezione 7.2 dei tutorial per maggiori informazioni sugli effetti.

Copia il codice su un buffer vuoto e ascoltalo. Non fermarlo, metti mano al codice. Cambia i tempi di slide, cambia le note, i synth, gli effetti e i tempi di sleep. Vedi se riesci a creare qualcosa di totalmente differente!

live_loop :moon_rise do
  with_fx :echo, mix: 0, mix_slide: 8 do |fx|
    control fx, mix: 1
    notes = (scale :e3, :minor_pentatonic, num_octaves: 2).shuffle
    sn = synth :prophet , sustain: 8, note: :e1, cutoff: 70, cutoff_slide: 8
    control sn, cutoff: 130
    sleep 2
    32.times do
      control sn, note: notes.tick, pan: rrand(-1, 1)
      sleep 0.125
    end
  end
end

- Tenere traccia del beat

Il mese scorso in questa serie abbiamo parlato in modo approfondito della casualità alla base di Sonic pi. Abbiamo capito come poterla sfruttare in modo deterministico per aggiungere nuovi livelli di controllo del nostro codice. Questo mese continueremo questa analisi approfondendo il sistema di tick di Sonic Pi. Alla fine di questo articolo utilizzerai i tick per i tuoi ritmi e nei tuoi riff per diventare un DJ live coder.

Contrare i battiti

Quando facciamo musica spesso vogliamo che accada qualcosa in base al beat in cui ci troviamo. Sonic Pi ha un sistema di conteggio chiamato tick per avere totale controllo di dove ci troviamo nella battuta e, ovviamente, supporta beat multipli ciascuno col suo tempo.

Diamoci da fare, per avanzare nel beat dobbiamo solo chiamare tick. Apriamo un buffer vuoto, scriviamo il seguente codice e premiamo su Run:

puts tick #=> 0

Ci verrà restituito il beat corrente, quindi 0. Nota come anche premendo Run più volte il risultato sarà sempre 0. Questo perché ad ogni avvio, il beat riparte da 0. Tuttavia, mentre Run è ancora attivo, possiamo avanzare nel beat tutte le volte che vogliamo:

puts tick #=> 0
puts tick #=> 1
puts tick #=> 2

Quando vedi il simbolo #=> alla fine di una riga vuol dire che quella linea di codice restituirà del testo nel log nella parte destra. Per esempio puts foo #=> 0 significa che il codice puts foo scriverà 0 nel log.

Controllare il beat

Abbiamo visto che tick fa due cose: incrementa di uno il beat e restituisce il valore corrente. A volte vogliamo solo vedere il valore corrente senza incrementalo. Possiamo farlo usando look:

puts tick #=> 0
puts tick #=> 1
puts look #=> 1
puts look #=> 1

In questo codice usiamo il tick per aumentare la pulsazione due volte e poi usiamo look, anch’esso due volte. Nel log vedremo questi valori: 0, 1, 1, 1. I primi due tick restituiscono 0 e 1 come ci aspettiamo i due look restituiscono l’ultimo valore due volte, ovvero 1.

Anelli

Quindi ora possiamo avanzare nel tempo con tick e controllare il beat con look. Cosa possiamo fare ancora? Dobbiamo avere qualcosa con cui usare tick. Sonic Pi utilizza gli anelli (ring) per rappresentare i riff, melodie e ritmi e il sistema dei tick è stato pensato per lavorare con essi. Di fatto gli anelli hanno la loro versione di tick che fa due cose. Innanzitutto funziona come un tick normale e incrementa il beat. In secondo luogo guarda il valore del ring utilizzano il valore del beat come indice. Diamo un’occhiata:

puts (ring :a, :b, :c).tick #=> :a

.tick è una versione speciale di tick che ritornerà il primo valore del ring :a. Possiamo prendere ciascun valore del ring chiamando .tick più volte:

puts (ring :a, :b, :c).tick #=> :a
puts (ring :a, :b, :c).tick #=> :b
puts (ring :a, :b, :c).tick #=> :c
puts (ring :a, :b, :c).tick #=> :a
puts look                   #=> 3

Prova a guarda il log e vedrai :a, :b, :c e poi di nuovo :a. Nota come look restituisce 3. Le chiamate a .tick funzionano come normali chiamate di tick, incrementano il beat locale.

Un arpeggiatore con Live Loop

La vera potenza viene fuori quando utilizziamo tick con ring e live_loop. Quando combiniamo queste cose abbiamo tutti gli strumenti per costruite un semplice arpeggiatore. Abbiamo bisogno di quattro cose:

Un anello (ring) che contenga le note che vogliamo ripetere. Un mezzo per incrementare e ottenere il valore del beat. La possibilità di suonare una nota basata sul beat corrente. Una struttura di loop per continuare a ripetere l’arpeggiatore.

Tutti questi concetti possono essere ritrovati in questo codice:

notes = (ring 57, 62, 55, 59, 64)
live_loop :arp do
  use_synth :dpulse
  play notes.tick, release: 0.2
  sleep 0.125
end

Guardiamo ciascuna linea di codice. Per prima cosa definiamo un ring di note che continuerà a suonare. Dopodiché creiamo un live_loop chiamato :arp che continuerà a ripetersi. Ogni volta che si ripete il live_loop, impostiamo il synth per essere :dpulse e poi suonando la nota successiva usando .tick. Ricorda che questo incrementerà il nostro contatore di beat e userà l’ultimo valore di beat come indice nel nostro anello. Alla fine, aspettiamo per 1/8 di beat prima di ricominciare da capo.

Beat multipli simultanei

Una cosa importante da sapere è che i tick valgono localmente nel live_loop. Questo significa che ciascun live_loop ha il suo contatore beat indipendente. Questa cosa è molto più potente che avere un metronomo globale e un beat. Proviamo a vederlo in azione:

notes = (ring 57, 62, 55, 59, 64)
with_fx :reverb do
  live_loop :arp do
    use_synth :dpulse
    play notes.tick + 12, release: 0.1
    sleep 0.125
  end
end
live_loop :arp2 do
  use_synth :dsaw
  play notes.tick - 12, release: 0.2
  sleep 0.75
end

Scontri tra beat

Una cosa che causa confusione con il sistema di tick di Sonic Pi è che le persone vogliono utilizzare il tick in più ring nello stesso live_loop:

use_bpm 300
use_synth :blade
live_loop :foo do
  play (ring :e1, :e2, :e3).tick
  play (scale :e3, :minor_pentatonic).tick
  sleep 1
end

Anche se ciascun live_loop ha il suo beat counter indipendente, stiamo chiamando .tick due volte all’interno dello stesso live_loop. Questo significa che il beat verrà incrementato due volte ogni loop. Questo può generare dei poliritmi interessanti ma spesso non è quello che vogliamo. Ci sono due soluzioni per questo problema. Una è chiamare tickall’inizio del live_loop per poi usare .look per controllare il valore; la seconda è dare un nome a ogni chiamata .tick come, ad esempio .tick(:foo). Sonic Pi creerà e terrà traccia di un contatore di beat per ciascun nome che utilizzerai. In questo modo puoi lavorare con quanti beat tu voglia! Prova a vedere la sezione 9.4 dei tutorial per maggiori informazioni.

Mettiamo tutto insieme

Mettiamo insieme tutto quello che abbiamo imparato su tick, ring e live_loop per un ultimo esempio. Come al solito, non trattarlo come un pezzo finito. Prova a cambiare le cose e a giocare con questo codice per vedere cosa riesci a combinare. Alla prossima…

use_bpm 240
notes = (scale :e3, :minor_pentatonic).shuffle
live_loop :foo do
  use_synth :blade
  with_fx :reverb, reps: 8, room: 1 do
    tick
    co = (line 70, 130, steps: 32).tick(:cutoff)
    play (octs :e3, 3).look, cutoff: co, amp: 2
    play notes.look, amp: 4
    sleep 1
  end
end
live_loop :bar do
  tick
  sample :bd_ada if (spread 1, 4).look
  use_synth :tb303
  co = (line 70, 130, steps: 16).look
  r = (line 0.1, 0.5, steps: 64).mirror.look
  play notes.look, release: r, cutoff: co
  sleep 0.5
end

- Tagliare i campioni

Nel terzo episodio di questa serie su Sonic Pi, abbiamo visto come loopare, allungare e filtrare uno dei più famosi break di batteria di tutti i tempi. L’Amen Break. In questo tutorial faremo un passo in avanti per vedere come tagliuzzarlo, riordinare i pezzi e incollare di nuovo tutto insieme in un ordine completamente nuovo. Se ti sembra un po’ pazzo, non ti preoccupare; diventerà tutto chiaro non appena capirei come usare un nuovo strumento per i tuoi set di live coding.

Il suono come dati

Prima di cominciare, prendiamo un momento per analizzare come lavorare con i campioni. Fino ad ora, avrai utilizzato il campionatore di Sonic Pi. Se non l’hai fatto, è il momento di cominciare! Accendi il tuo Rasberry Pi, apri Sonic Pi dal menu Programming e scrivi il seguente codice in un buffer vuoto e poi premi il pulsante Run per sentire un beat di batteria pre-registrato:

sample :loop_amen

Una registrazione di un suono può essere rappresentato come un flusso di dati: un sacco di numeri compresi tra -1 e 1 che rappresentano i picchi e, più in generale, l’onda sonora. Se suoniamo questi numeri in ordine, otteniamo il suono originale. Ma se decidessimo di suonarli in un ordine diverso per creare un nuovo suono?

Come sono registrati i campioni? È una cosa abbastanza semplice una volta capita la fisica del suono. Quando produci un suono, per esempio colpendo una batteria, il rumore viaggia attraverso l’aria in modo simile al comportamento delle increspature della superficie del lago quando lanci un sasso. Quando queste increspature raggiungono le tue orecchie, il timpano si muove per simpatia e converte questi movimento nel suono che tu ascolti. Se vogliamo registrare e riprodurre un suono, dobbiamo catturare, salvare e riprodurre quelle increspature. Possiamo usare un microfono che agisce come un timpano e si muove avanti e indietro quando il suono lo colpisce. Il microfono converte la sua posizione in un un segnale elettrico che viene misurato molte volte al secondo. Queste misurazioni sono poi rappresentate da una serie di valori compresi tra -1 e 1.

Se dovessimo rappresentare graficamente il suono, risulterebbe un grafico di dati con il tempo sull’asse x e la posizione del microfono/speaker come un valore tra -1 e 1 sull’asse y. Puoi vedere un esempio di questo grafico in cima al diagramma.

Suonare una parte di un campione

Quindi, come programmiamo Sonic Pi per suonare un campione in ordine differente? Per rispondere a questa domanda, dobbiamo dare un’occhiata ai parametri start: e finish: di sample. Questi valori ci permettono di controllare la posizione iniziale della riproduzione dei numeri che rappresentano i suoni. I valori di questi parametri possono essere rappresentati da numeri compresi tra 0 e 1 dove 0 rappresenta l’inizio del campione e 1 la fine. Per cui, per suonare la prima metà dell’Amen Break, è sufficiente specificare un valore di finish: pari a 0.5:

sample :loop_amen, finish: 0.5

Possiamo aggiungere un valore start: per suonare una porzione del campione:

sample :loop_amen, start: 0.25, finish: 0.5

Per puro divertimento, puoi avere il parametro finish: che sia prima di start: e il campione suonerà al contrario:

sample :loop_amen, start: 0.5, finish: 0.25

Riordinare la riproduzione del campione

Ora che abbiamo capito che i campioni sono un semplice elenco di numeri che possono essere riprodotti in qualsiasi ordine e abbiamo capito come riprodurre una parte specifica; ora possiamo divertirci suonando un campione in un ordine ‘sbagliato’.

Amen Slices

Prendiamo il nostro Amen Break e tagliamolo in 8 parti uguali e poi riordiniamo i vari pezzi. Dai un’occhiata all’immagine; all’inizio A) rappresenta il grafico dei nostri dati originali. Tagliarlo in 8 parti diventa B) - nota come abbiamo assegnato un colore differente a ciascun pezzo per aiutarci a distinguerli. Puoi vedere i valori di inizio e di fine di ciascun pezzo all’inizio. Infine C) è una possibilità di riordinare i pezzi. Poi possiamo suonarlo per creare un nuovo beat. Dai un’occhiata a questo codice:

live_loop :beat_slicer do
  slice_idx = rand_i(8)
  slice_size = 0.125
  s = slice_idx * slice_size
  f = s + slice_size
  sample :loop_amen, start: s, finish: f
  sleep sample_duration :loop_amen, start: s, finish: f
end

Abbiamo scelto un pezzo in modo casuale prendendo un numero compreso tra 0 e 7 (ricordati che iniziamo a contare da 0). Sonic Pi ha una funzione che ci viene in aiuto: rand_i(8). Dopodiché salviamo il valore di indice nella variabile slice_idx. Definiamo la nostra slice_size che è 1/8 o 0.125. Il parametro slice_size è necessario per noi per convertire slice_idx in un valore compreso tra 0 e 1 per poterlo usare come parametro di start:. Calcoliamo la posizione iniziale s moltiplicando l’indice slice_idx per la dimensione slice_size. Calcoliamo la posizione finale f aggiungendo la dimensione della sottosequenza slice_size alla posizione iniziale s. Ora possiamo riprodurre i pezzi del campione agganciando i valori s e f dentro i parametri start: e finish: di sample. Prima di iniziare a suonare il pezzo successivo, dobbiamo sapere quanto lungo deve essere il valore di sleep che dovrebbe essere uguale alla durata del pezzo del campione. Per fortuna Sonic Pi ha la funzione sample_duration che accetta gli stessi parametri di sample e restituisce il valore della durata. Per cui, passando il valore sample_duration ai parametri start: e finish:, possiamo conoscere la durata di un singolo pezzo. Inseriamo tutto questo codice in un live_loop per poter continuare a scegliere di suonare un pezzo casualmente.

Mettiamo tutto insieme

Combiniamo tutto quello che abbiamo visto fino ad ora in un ultimo esempio che rappresenti come usare un approccio simile per combinare pezzi di campione con una nuova linea di basso per creare l’inizio di una traccia. Ora è il tuo turno, prendi il codice qui sotto come punto di partenza e vedi se puoi trovare la tua strada per creare qualcosa di nuovo…

live_loop :sliced_amen do
  n = 8
  s =  line(0, 1, steps: n).choose
  f = s + (1.0 / n)
  sample :loop_amen, beat_stretch: 2, start: s, finish: f
  sleep 2.0  / n
end
live_loop :acid_bass do
  with_fx :reverb, room: 1, reps: 32, amp: 0.6 do
    tick
    n = (octs :e0, 3).look - (knit 0, 3 * 8, -4, 3 * 8).look
    co = rrand(70, 110)
    synth :beep, note: n + 36, release: 0.1, wave: 0, cutoff: co
    synth :tb303, note: n, release: 0.2, wave: 0, cutoff: co
    sleep (ring 0.125, 0.25).look
  end
end

- Programma un Sequencer Probabilistico

In un precedente episodio della serie su Sonic Pi abbiamo scoperto il potere della randomizzazione, utile a introdurre varietà e sorpresa durante le nostre sessioni di live coding. Per esempio, abbiamo scelto a caso delle note da una scala per comporre melodie infinite. Oggi impareremo una nuova tecnica che usa la randomizzazione per i beat del ritmo!

Probabilità

Prima di cominciare a creare ritmi e synth, facciamo una breve panoramica su concetti base di probabilità. Detta così può sembrare complicato e spaventoso ma, in realtà, è tanto semplice quanto lanciare un dado. Quando lanci un normale dado a 6 facce in un gioco da tavolo cosa succede? Al primo tentativo i numeri 1, 2, 3, 4, 5 e 6 avranno tutti la stessa probabilità di uscire. Di fatto, essendo un dado a 6 facce, in media (se lo lanci molte volte) ti uscirà il numero 1 ogni 6 lanci. Questo significa avere una possibilità di 1 su 6 che esca 1. Possiamo simulare lo stesso comportamento in Sonic Pi utilizzando la funzione dice. Lanciamone uno 8 volte:

8.times do
  puts dice
  sleep 1
end

Nota come il log mostri valori tra 1 e 6 esattamente come se avessimo lanciato un vero dado.

Beat casuali

Ora, immagina di avere una batteria e che ogni volta che stai per colpirla decidi di lanciare un dado. Se esce 1, colpisci la batteria altrimenti no. Ora abbiamo una drum machine probabilistica che funziona con una probabilità di 1/6. Proviamo a sentire il risultato:

live_loop :random_beat do
  sample :drum_snare_hard if dice == 1
  sleep 0.125
end

Guardiamo ogni riga di codice per essere sicuri che sia tutto chiaro. Per prima cosa creiamo un nuovo live_loop chiamato :random_beat che si ripeterà continuamente tra le righe do e end. La prima di queste righe è una chiamata a sample che riprodurrà un suono preregistrato (in questo caso il suono :drum_snare_hard). Tuttavia questa riga ha una condizione ifalla fine. Questo significa che la linea verrà eseguita se la condizione che è scritta alla destra di if risulterà true (vero). In questo caso: dice == 1. Questa è una chiamata alla funzione dice che, come abbiamo visto, restituisce un valore tra 1 e 6. Usiamo l’operatore == per verificare se il valore è uguale a 1. Se è così, la condizione restituisce true e viene riprodotto il suono di rullante, se il numero è diverso da 1 restituisce false e il rullante viene saltato. La seconda linea aspetta semplicemente che passino 0.125 secondi prima di lanciare nuovamente il dado.

Cambiare le probabilità

Quelli di voi che hanno fatto giochi di ruolo sanno che esistono dadi di diverse forme e con differenti numeri di facce. Per esempio esiste il dato a forma di tetraedro che ha solo 4 lati oppure l’icosaedro che, invece, ha 20 facce. Il numero di facce determina il cambiamento nella probabilità che esca 1. Minore è il numero di facce, più probabilità hai che esca 1. Per esempio in un dato a 4 facce, c’è 1 possibilità su 4 mentre in quello da 20 è 1 su 20. Per fortuna Sonic Pi ha la funzione one_in che descrive esattamente questo. Proviamo:

live_loop :different_probabilities do
  sample :drum_snare_hard if one_in(6)
  sleep 0.125
end

Facendo partire il live loop qui sopra, sentirai un ritmo casuale familiare. Ora: non fermare la musa ma cambia il 6 con un valore diverso come 2 o 20 e premi nuovamente Run. Nota come più basso è il numero più frequentemente senti il suono di rullante mentre più è alto il numero minori sono le probabilità che venga suonato. Stai creando musica con le probabilità!

Combinare le probabilità

Le cose si fanno davvero interessanti quando diversi campioni vengono avviati con diverse probabilità. Per esempio:

live_loop :multi_beat do
  sample :elec_hi_snare if one_in(6)
  sample :drum_cymbal_closed if one_in(2)
  sample :drum_cymbal_pedal if one_in(3)
  sample :bd_haus if one_in(4)
  sleep 0.125
end

Prova a far partire il codice qui sopra cambiando ancora una volta le probabilità per modificare il ritmo. Puoi provare anche a cambiare il sample per cambiare completamente il sentimento. Modifica :drum_cymbal_closed in :bass_hit_c per avere del basso extra!

Ritmi ripetibili

Infine, possiamo usare il caro vecchio use_random_seed per resettare il flusso casuale dopo 8 iterazioni per creare un beat regolare. Scrivi il seguente codice per sentire un ritmo più regolare e ripetitivo. Una volta ascoltato, prova a cambiare il valore di seed da 1000 a un altro numero. Nota come numeri differenti generato beat diversi.

live_loop :multi_beat do
  use_random_seed 1000
  8.times do
    sample :elec_hi_snare if one_in(6)
    sample :drum_cymbal_closed if one_in(2)
    sample :drum_cymbal_pedal if one_in(3)
    sample :bd_haus if one_in(4)
    sleep 0.125
  end
end

Solitamente, con questo tipo struttura bisogna ricordarsi quali semi suonano bene e prenderne nota. In questo modo, posso facilmente riproporre dei ritmi che ho già creato in concerti futuri.

Mettiamo tutto insieme

Infine possiamo aggiungere un suono di basso casuale per dare un po’ di contenuto melodico. Ricorda che possiamo usare il sistema di sequenze probabilistiche che abbiamo appena scoperto non solo per i sample ma anche per i sintetizzatori. Non lasciarlo così com’è, cambia i numeri e crea la tua traccia con la potenza delle probabilità!

live_loop :multi_beat do
  use_random_seed 2000
  8.times do
    c = rrand(70, 130)
    n = (scale :e1, :minor_pentatonic).take(3).choose
    synth :tb303, note: n, release: 0.1, cutoff: c if rand < 0.9
    sample :elec_hi_snare if one_in(6)
    sample :drum_cymbal_closed if one_in(2)
    sample :drum_cymbal_pedal if one_in(3)
    sample :bd_haus, amp: 1.5 if one_in(4)
    sleep 0.125
  end
end

- Modulazione d’ampiezza

Questo mese scopriremo tutti i segreti di uno degli effetti più potenti e flessibili di Sonic Pi: lo :slicer. Alla fine di questo articolo avrete imparato come manipolare il volume generale di alcune parti dei suoni programmati dal vivo. Questo vi permetterà di creare nuove strutture ritmiche e timbriche e di allargare le possibilità sonore.

Affetta quell’amp

Cosa fa esattamente l’effetto :slicer? Possiamo pensarlo come qualcuno che gioca con il controllo del volume della vostra TV o impianto hi-fi. Prima di approfondire il discorso, ascoltate il suono profondo del synth :prophet generato con questo codice:

synth :prophet, note: :e1, release: 8, cutoff: 70
synth :prophet, note: :e1 + 4, release: 8, cutoff: 80

Ora inseriamo l’effetto :slicer:


with_fx :slicer do
  synth :prophet, note: :e1, release: 8, cutoff: 70
  synth :prophet, note: :e1 + 4, release: 8, cutoff: 80
end

Visto come lo slicer agisce? Sembra che silenzi e poi riattivi l’audio con un ritmo regolare. Sembra anche che ‘:slicer’ abbia effetto sul suono generato dal codice scritto tra i blocchi ‘do’ e ‘end’. Puoi controllare la velocità a cui il suono viene spento e riacceso con lopzione ‘phase:’ che è l’abbreviazione di durata di fase in inglese (phase duration). Il valore predefinito è ‘0.25’, il che significa che lo status cambia 4 volte al secondo quando i BPM sono a 60. Proviamo a mandarlo più veloce:

with_fx :slicer, phase: 0.125 do
  synth :prophet, note: :e1, release: 8, cutoff: 70
  synth :prophet, note: :e1 + 4, release: 8, cutoff: 80
end

Ora, prova a suonare con differenti valori di ‘:phase’. Prova valori più lunghi o più brevi. Guarda cosa accade quando scegli valori molto brevi. Poi, prova anche a cambiare synth, tipo ‘:beep’ oppure ‘:dsaw’ e anche note differenti. Osserva il diagramma seguente per capire come valori di ‘:phase’ diversi cambino il numero di cambiamenti di ampiezza per ogni battito.

Phase Durations

La durata di una fase corrisponde alla durata del tempo per un ciclo on/off. Pertanto valori più piccoli porteranno ad un passaggio molto più veloce da on a off rispetto a valori più grandi. Dei buoni valori di partenza sono 0.125, 0.25, 0.5 e 1.

Onde di controllo

Di base, l’effetto ‘:slicer’ usa un’onda quadra per cambiare l’ampiezza d’onda nel tempo. Questo è il motivo per cui sentiamo il suono per un periodo e successivamente questo scompare per poi ricomparire e così via. Però l’effetto ‘:slicer’ può usare 4 diverse forme d’onda per modificare il suono, che sono la dente di sega, la triangolare e la cosinusoidale. Dai un’occhiata al diagramma sotto per capire la loro forma. Possiamo anche ascoltare il loro effetto. Per esempio, se digiti il codice seguente userai l’onda cosinusoidale come onda di controllo. Infatti, in questo caso il suono non si spegne e accende a scatti, ma in maniera progressiva e senza brusche interruzioni:

with_fx :slicer, phase: 0.5, wave: 3 do
  synth :dsaw, note: :e3, release: 8, cutoff: 120
  synth :dsaw, note: :e2, release: 8, cutoff: 100
end

Suona provando a cambiare le forme d’onda attraverso l’opzione ‘wave:’: ‘0’ sta per dente di sega, ‘1’ per onda quadra, ‘2’ per triangolare e ‘3’ per sinusoidale. Prova anche a variare la fase attraverso ‘phase:’ a ogni forma d’onda per sentire come cambia il suono.

Ognuna di queste onde può essere invertita utilizzando l’opzione ‘invert_wave:’ che la ribalta sull’asse y. Per esempio, durante un ciclo normale l’onda a dente di sega parte dall’alto e si dirige lentamente verso il basso raggiungendo il punto in cui immediatamente ritorna al valore massimo. Invertendo la forma d’onda con ‘invert_wave:1’, l’onda partirà dal valore minimo ed andrà lentamente verso il valore massimo fino a quando ricadrà improvvisamente al valore minimo. Un’altra opzione è ‘phase_offset:’ per mezzo del quale possiamo far iniziare l’onda da un punto qualsiasi. Il valore inserito deve essere tra ‘0’ e ‘1’. Quindi, giocando con i valori di ‘phase:’, wave:’, ‘invert_wave:’ e ‘phase_offset:’ puoi cambiare, e di molto, il comportamento dell’ampiezza dell’onda nel tempo.

Phase Durations

Imposta i tuoi livelli

Di base, ‘:slicer’ passa dai valore ‘1’ (volume massimo) e ‘0’ (silenzioso). Questi valori possono essere cambiati per mezzo delle opzione ‘amp_min’ e ‘amp_max’. Puoi cambiare questi valori accoppiandoli con un’onda sinusoidale per creare un effetto tremolo:

with_fx :slicer, amp_min: 0.25, amp_max: 0.75, wave: 3, phase: 0.25 do
  synth :saw, release: 8
end

Succederebbe praticamente la stessa cosa se prendessi il controllo del volume del tuo impianto stereo e lo muovessi in su e giù facendo ondeggiare il suono.

Probabilità

Una delle caratteristiche più divertenti di ‘:slicer’ è la possibilità di usare la probabilità per decidere se accendere o spegnere lo slicer. Con questa possibilità, il sistema lancia un dado prima di ogni fase e agisce seguendo il valore che viene fuori. Prova a digitare e eseguire quanto segue:

with_fx :slicer, phase: 0.125, probability: 0.6  do
  synth :tb303, note: :e1, cutoff_attack: 8, release: 8
  synth :tb303, note: :e2, cutoff_attack: 4, release: 8
  synth :tb303, note: :e3, cutoff_attack: 2, release: 8
end

Abbiamo ottenuto un interessante ritmo di impulsi. Prova a cambiare l’opzione ‘probability:’ (probabilità) con un valore tra ‘0’ e ‘1’. Più ti avvicini allo ‘0’, più i suoni saranno spaziati tra loro perché la probabilità di accensione dell’effetto risulta più bassa.

Il sistema delle probabilità usato negli effetti è lo stesso utilizzato per la randomizzazione in funzioni come ‘rand’ e ‘shuffle’. Sono entrambi completamente deterministici. Ciò significa che tutte le volte che premi Run, sentirai sempre la stessa sequenza per una data probabilità. Se volessi cambiare la sequenza ottenuta puoi usare l’opzione ‘seed:’ cambiando il seme di riferimento. Funziona esattamente come ‘use_random_seed’, soltanto in questo caso si agisce su quel particolare effetto e basta.

Infine, con l’opzione ‘prob_pos:’ puoi cambiare la posizione di riposo dell’onda di controllo quando il test di probabilità fallisce tra il valore ‘0’ e un altro qualsiasi punto:

with_fx :slicer, phase: 0.125, probability: 0.6, prob_pos: 1  do
  synth :tb303, note: :e1, cutoff_attack: 8, release: 8
  synth :tb303, note: :e2, cutoff_attack: 4, release: 8
  synth :tb303, note: :e3, cutoff_attack: 2, release: 8
end

Affettare i beat

Una cosa davvero molto divertente è usare ‘:slicer’ per affettare un beat di batteria:

with_fx :slicer, phase: 0.125 do
  sample :loop_mika
end

Questo ci permette di creare nuove possibilità ritmiche utilizzando un qualsiasi campione, il che è piuttosto divertente. Tuttavia, bisogna star attenti a che la durata dei campioni sia coerente con i BPM impostati in Sonic Pi, altrimenti l’azione di affettamento non funzionerà. Per esempio, prova a cambiare da ‘:loop_mika’ a ‘:loop_amen’ e ascolta come suona male quando la durata non coincide.

Cambiamenti di tempo

Come abbiamo già visto, cambiare i BPM preimpostati con ‘use_bpm’ farà anche cambiare i tempi di ‘sleep’ e gli le durate degli inviluppi coerentemente al nuovo valore. L’effetto ‘:slicer’ si comporta nello stesso modo e l’opzione ‘phase:’ è in realtà misurata in battiti e non in secondi. Quindi possiamo risolvere il problema di ‘loop_amen’ appena visto cambiando i BPM e farli coincidere con quelli del campione:

use_sample_bpm :loop_amen
with_fx :slicer, phase: 0.125 do
  sample :loop_amen
end

Mettiamo tutto insieme

Quindi, applichiamo le idee esposte sopra nell’esempio finale che utilizza soltanto l’effetto ‘:slicer’ per creare una combinazione interessante. Vai avanti, cambia quanto scritto e componi il tuo brano personale!

live_loop :dark_mist do
  co = (line 70, 130, steps: 8).tick
  with_fx :slicer, probability: 0.7, prob_pos: 1 do
    synth :prophet, note: :e1, release: 8, cutoff: co
  end
  
  with_fx :slicer, phase: [0.125, 0.25].choose do
    sample :guit_em9, rate: 0.5
  end
  sleep 8
end
live_loop :crashing_waves do
  with_fx :slicer, wave: 0, phase: 0.25 do
    sample :loop_mika, rate: 0.5
  end
  sleep 16
end

- Cinque tecniche di live coding

Nella guida di questo mese ti spiegheremo che Sonic Pi può essere utilizzato come un vero strumento musicale. Quindi dobbiamo cominciare a pensare al codice in un modo completamente diverso. I live coder pensano al codice più o meno nello stesso modo in cui un violinista pensa al suo archetto. Infatti, come il violinista può usare diverse tecniche esecutive per creare suoni diversi (movimento lento e colpetti veloci per esempio), noi esploreremo qui 5 regole di base del live coding che si possono eseguire su Sonic Pi. Alla fine di questo articolo, tu sarai capace di eseguire la tua musica per mezzo del live coding.

1. Memorizza i tasti di scelta rapida

Uno dei primi consigli da seguire a proposito del live coding, è quello di cominciare ad usare le combinazioni di tasti (shortcut). Ad esempio, invece di perdere tempo cercando il mouse, muoverlo sul bottone Run e cliccarlo, puoi semplicemente premere alt e r contemporaneamente. Oltre ad essere molto più veloce, le tue dita saranno già sulla tastiera pronte a digitare il prossimo comando. Puoi vedere ognuna delle combinazioni per le funzioni principali andando con il cursore del mouse sopra il pulsante relativo alla funzione stessa. Oppure, al paragrafo 10.2 del tutorial puoi trovare l’intera lista.

Mentre stai suonando, una cosa divertente da fare è dare un po’ di enfasi al movimento delle braccia quando effettui una combinazione di tasti. Ad esempio, è sempre buona cosa comunicare agli spettatori quando stai per introdurre un cambiamento, quindi amplifica il gesto quando digiti alt-r, al pari di un chitarrista che dà una potente pennata.

2. Stratifica manualmente i tuoi suoni

Ora puoi far partire codice istantaneamente con la tastiera, puoi usare subito questa abilità per la nostra seconda tecnica che consiste nello stratificare suoni in modo manuale. Invece di ‘comporre’ usando molte chiamate a play e sample separate da sleep avremo un’unica chiamata a play che avvieremo automaticamente usando alt-r. Proviamo! Inserisci questo codice in un buffer vuoto:

synth :tb303, note: :e2 - 0, release: 12, cutoff: 90

Ora, premi Avvia e, mentre il suono viene riprodotto, modifica il codice in modo da eliminare quattro note cambiando il seguente codice:

synth :tb303, note: :e2 - 4, release: 12, cutoff: 90

Ora, premi Avvia di nuovo per sentire entrambi i suoni nello stesso momento. Questo perché il pulsante Avvia di Sonic Pi non aspetta di finire di eseguire il codice già avviato ma, invece, fa partire il codice già avviato nello stesso momento. Questo vuol dire che puoi stratificare molti suoni semplicemente e manualmente con piccole modifiche tra un avvio e l’altro. Per esempio, prova a cambiare note: e cutoff: e a rilanciare il codice.

Puoi usare questa tecnica con campioni lunghi. Per esempio:

sample :ambi_lunar_land, rate: 1

Prova facendo partire il campione e, poi, abbassa progressivamente il valore di rate: da 1 a 0.5 a 0.25 fino a 0.125 premendo continuamente Avvia. Prova anche con valori negativi come -0.5. Stratifica i suoni e vedi dove puoi arrivare. Prova anche ad aggiungere degli effetti.

Quando ti esibisci, lavorare con linee di codice molto semplice può aiutare il pubblico che non ha mai visto Sonic Pi a seguire quello che stai facendo riuscendo a collegare quanto stati scrivendo con quello che sentono.

3. Controllare i live loop

Quando si lavora con della musica più ritmata, può risultare spesso difficile sincronizzare tutto e mantenere un buon tempo. In questi casi è preferibile utilizzare un ‘live_loop’. Oltre a garantire la ripetizione al tuo codice, ti dà la possibilità di modificarlo, aggiornandolo per la prossima iterazione. Inoltre, allo stesso tempo altri live_loop possono essere eseguiti, il che significa che è possibile sovrapporli fra loro, o a istruzioni manuali. Dai un’occhiata alla sezione 9.2 del tutorial per ulteriori informazioni sull’utilizzo dei live loop.

Quando esegui un’esecuzione dal vivo, ricordarti di utilizzare nel live_loop l’opzione sync: in modo da rimediare ad eventuali errori di runtime che possono interrompere l’esecuzione in loop del tuo brano. Se hai già introdotto un sync: che punta a un altro valido live_loop, allora si può rapidamente correggere l’errore, eseguendo nuovamente il codice e ripartire senza perdere il tempo.

4. Usare il mixer master

Uno dei segreti meglio custoditi di Sonic Pi è che esiste un mixer principale attraverso il quale confluiscono tutti i suoni. Questo mixer ha di fabbrica sia un filtro passa-basso che un filtro passa-alto, quindi è possibile operare facilmente delle modifiche globali al suono in uscita. Le funzionalità del mixer principale sono accessibili tramite la funzione set_mixer_control!. Ad esempio, mentre del codice è in esecuzione e sta suonando, basta inserire la funzione in un buffer vuoto ed eseguire Run:

set_mixer_control! lpf: 50

Dopo l’esecuzione di questo codice, verrà attivato un filtro passa basso, ottenendo un suono finale più “ovattato”. Nota bene che i nuovi parametri del mixer principale verranno mantenuti finché non deciderai di modificarli nuovamente. Tuttavia, è possibile reimpostare in qualsiasi momento il mixer al suo stato predefinito con la funzione reset_mixer!. Alcune delle opzioni attualmente supportate sono: pre_amp:, lpf: hpf:, e amp:. Per l’elenco completo, dai un’occhiata alla documentazione relativa a set_mixer_control!.

Utilizza l’opzione ‘ * _slide’ del mixer per far scorrere uno o molti valori delle opzioni nel tempo. Ad esempio, per far scorrere lentamente i valori del filtro passa-basso del mixer dal valore corrente a 30, prova a digitare il codice seguente:

set_mixer_control! lpf_slide: 16, lpf: 30

Puoi scorrere velocemente a un valore più alto così:

set_mixer_control! lpf_slide: 1, lpf: 130

Quanto ti esibisci può tornare utile tenere un buffer disponibile per lavorare con il mixer in questo modo.

5. Pratica

La tecnica più importante di live coding è fare pratica. La qualità più comune tra i musicisti professionisti di qualsiasi tipo è che fanno pratica con il loro strumento spesso per molte ore al giorno. Esercitarsi è importante per un live coder tanto quanto per un chitarrista. Fare esercizio permette alle tue dita di memorizzare alcuni pattern e modifiche comuni per cui puoi digitare e lavorare in modo più fluido. L’esercizio ti dà anche l’opportunità di esplorare nuovi suoni e codici.

Quando ti esibisci, scoprirai che più esercizio fai, più sarà semplice rilassarsi durante il concerto. La pratica ti permetterà di avere un catalogo di esperienze da cui prendere spunto. Questo ti permette di capire che tipo di modifiche saranno interessanti e quali funzioneranno bene con i suoni che stai utilizzando in quel momento.

Mettiamo tutto insieme

Questo mese, invece di presentare un esempio riassuntivo delle cose già fatte, iniziamo con una sfida. Prova a vedere se riesci a esercitarti tutti i giorni della settimana con gli esercizi che ti fornirò. Ad esempio, un giorno fai pratica con i trigger manuali, il successivo crea quale ‘live_loop’, quelo ancora dopo esercitati con il mixer principale, e così via. Poi ripeti tutto da capo. Non preoccuparti se ti senti lento/a o goffo/a in un primo momento - basta che ti eserciti ogni giorno e prima di rendertene conto sarai davanti a un pubblico vero e suonerai come una rockstar, o meglio come una live coding star.


- 8 consigli per la pratica di live coding

Il mese scorso abbiamo dato un’occhiata alle cinque tecniche più importanti per impadronirsi e impratichirsi nel live coding. In altre parole, abbiamo visto come usare Pi Sonic per approcciarsi alla programmazione musicale nello stesso modo in cui ci approcceremmo a uno strumento musicale. Uno dei concetti importanti che abbiamo trattato è stato quello della pratica. Questo mese ci occuperemo invece di capire perché la pratica continua di live coding è importante e come dovresti cominciare.

Fai esercizio regolarmente

Il consiglio più importante è quello di assicurarti di fare pratica regolarmente. Come regola, posso dirti che io in genere mi esercito per 1-2 ore al giorno, ma anche 20 minuti per iniziare possono andare bene. “Poco ma spesso” è l’obbiettivo al quale puntare - quindi se hai a disposizione solo 10 minuti, è comunque un ottimo inizio.

Consiglio pratico n.1 - inizia a sviluppare la routine di fare pratica. Trovati un momento piacevole e rilassante del giorno e fai pratica ogni volta che puoi. In poco tempo, non vedrai l’ora di arrivare alla tua sessione di pratica.

Impara a digitare senza guardare la tastiera

Se osservi un musicista professionista mentre suona sul palco noterai sicuramente alcuni aspetti. In primo luogo, quando suona non guarda il proprio strumento. Le sue dita, braccia e il corpo in generale conoscono le azioni da compiere senza bisogno di pensarci su troppo tempo. Questa abilità è chiamata “memoria muscolare” e anche se potrebbe sembrare qualcosa che solo i professionisti riescono a fare, in realtà questo processo funziona semplicemente come quando hai imparato per la prima volta a camminare o andare in bicicletta: hai fatto pratica attraverso la ripetizione. I e le live coder utilizzano la memoria muscolare per liberare le loro menti dal pensiero della gestione del movimento delle loro dita, in modo che possano concentrarsi sulla musica. Questa abilità è chiamata touch-type in inglese, e corrisponde all’abilità di digitare sulla tastiera senza il bisogno di guardarla.

Consiglio pratico n.2 - imparare a dattilografare. Ci sono molte applicazioni, siti web e anche i giochi che ti possono aiutare a raggiungere questo obiettivo. Trova quello che ti piace di più e rimanici incollato/a finché non riuscirai a programmare senza guardare la tastiera.

Programma stando in piedi

Il corpo di un musicista si adatta alla pratica del proprio strumento. Ad esempio, un suonatore di tromba deve essere in grado di soffiare forte, un chitarrista ha bisogno di essere in grado di afferrare il manico con forza e un batterista deve essere in grado di suonare continuamente la batteria per lunghi periodi di tempo. Quindi, qual’è l’aspetto fisico nel live coding? Proprio come i e le DJ, i e le live coder in genere suonano stando in piedi e alcuni/e riescono anche a ballare mentre suonano! Se si fa pratica di live coding seduti a una scrivania, dopo sarà difficile adattarsi a suonare in piedi ad un concerto. Probabilmente troverai le due situazioni molto diverse tra loro e non sarà facile passare dall’una all’altra.

Consiglio pratico n.3 - stai in piedi mentre fai pratica. Il modo più semplice per farlo consiste nell’utilizzare una scrivania che tenga la tastiera all’altezza giusta di quando stai in piedi. Tuttavia, se come me non hai una a casa, ti posso dare un paio di consigli semplici ma efficaci. Il primo è quello di utilizzare un asse da stiro, che sembra funzionare piuttosto bene. Un altro è quello di impilare alcune scatole o libri di grandi dimensioni su una normale scrivania e posizionare la tastiera in cima alla torre. Inoltre, ti consiglio di fare un po’ di allungamenti prima di iniziare a suonare e prova anche a muoverti a ritmo durante la sessione. Ricordati, nessuno ti sta guardando, quindi divertiti e comportati naturalmente. Questo ti aiuterà anche quando sarai sul palco.

Esercitati sul set up

Molti strumenti musicali richiedono di essere assemblati e accordati prima di essere suonati. Almeno che non tu sia già una rockstar, con un autobus pieno di assistenti, dovrai preparare tutto da solo/a prima del tuo concerto. Di solito, questo è un momento piuttosto stressante ed è facile che emergano problemi. Una soluzione che può aiutarti è quella di incorporare nella pratica quotidiana anche la preparazione della strumentazione.

Consiglio pratico n.4. Inserisci il set-up nella tua routine di pratica quotidiana. Per esempio, procurati una scatola o una borsa in cui tenere il tuo Raspberry Pi, la tastiera ecc. Prima di ogni sessione di pratica, tira fuori tutte le parti, connettile e avvia il tutto fino a che non otterrai la schermata iniziale di Sonic Pi. Poi, quando avrai finito la tua sessione di pratica, lasciati il tempo di mettere tutto a posto con cura. All’inizio questa operazione potrebbe portarti via un po’ di tempo, ma poi diventerai pratico/a anche in questo e tutto sarà molto più facile e veloce. Non ci dovrai nemmeno pensare mentre lo fai.

Sperimenta musicalmente

Quando avrai sistemato tutto e sarai pronto/a per iniziare a suonare, potresti ritrovarti spaesato/a e non sapere dove cominciare. Molte persone hanno questo problema: trovare una buona idea da cui cominciare oppure avere una buona idea ma non sapere come realizzarla. Alcune persone addirittura non hanno proprio idea di che suoni vogliono fare! La prima cosa da fare è non preoccuparsi. Infatti è una situazione molto comune e succede ad ogni musicista, anche se hanno una lunga esperienza. E’ comunque molto meglio fare un suono che non ti piace piuttosto che non farne nessuno.

Consiglio pratico n. 5. Passa del tempo a fare suoni e musica che non ti piacciono. Prenditi il tempo di esplorare nuove idee e nuovi suoni. Non ti preoccupare se ti sembrano orribili o se non sono nello stile che volevi ottenere. Quando sperimenti in questo modo incrementi le possibilità di imbatterti in suoni o combinazioni di essi che potresti amare! Anche se il 99% dei suoni che fai sono brutti, quell’1% potrebbe contenere un riff da inserire nel tuo nuovo brano. Dimenticati delle cose che non ti piacciono e ricordati di quelle che ti piacciono. Far ciò è anche più facile quando suoni con il codice. Infatti, puoi semplicemente premere salva!

Ascolta il codice

Molti musicisti riescono a guardare uno spartito e “ascoltare” la musica nella propria testa senza aver bisogno di suonarla. Si tratta di una capacità davvero molto utile e vale la pena provare a trasferirla nei propri esercizi di live coding. In verità, la cosa veramente importante è avere idea di cosa una determinata istruzione andrà a suonare. Non è necessario essere in grado di immaginarlo esattamente, ma sapere perlomeno se sarà un qualcosa di veloce, lento, forte, ritmico, melodico, casuale, eccetera. L’obbiettivo è poter invertire il processo, immaginando quello che si vuol suonare e quindi decidere quali istruzioni andare a scrivere. Può volerci molto tempo per perfezionare questo processo, ma appena ci riesci, sarai in grado di improvvisare ed esprimere le tue idee sul palco in modo del tutto spontaneo.

Consiglio pratico n. 6. Scrivi codice dentro Sonic Pi ma non premere Run. Prova invece ad immaginarti che suono potrebbe produrre quel codice. Solo dopo premi Run, ascolta e prova a pensare a cosa hai fatto di giusto e di sbagliato. Continua a fare questo passaggio finché non diventa un’azione naturale della tua attività di programmazione. Quando io mi esercito, di solito ho un’idea piuttosto precisa di come quel pezzo di codice suonerà. Tuttavia, riesco ancora a volte a sorprendermi. In questi casi fermo il processo e cerco di capire perché ho pensato una cosa e n’è successa un’altra. Tutte le volte che succede questo, riesco a imparare nuovi trucchi che mi permettono di esprimermi in modi nuovi.

Rimuovi tutte le distrazioni

Un problema comune quando fai pratica è quello di essere distratti da altre cose. Far pratica è un’attività difficile e richiede una grande dose di disciplina, qualsiasi sia il tipo di musica che fai: jazz, classica o EDM. Se ti stai fortemente impegnando a iniziare oppure a migliorare le tue abilità, è spesso anche troppo facile andare sui social o cercare cose su internet. Se decidi di fare 20 minuti di pratica, è importante che questi 20 minuti siano dedicati totalmente a quell’attività e che siano il più produttivi possibile.

Consiglio pratico n.7. Prima di iniziare a fare pratica, cerca di eliminare quanti più elementi di distrazione possibile. Per esempio, disconnetti da internet, metti il telefono in un’altra stanza e cerca un posto per fare pratica in cui difficilmente verrai disturbato. Cerca di focalizzarti sulla tua attività di live coding e poi successivamente potrai tornare alle tue distrazioni quando avrai finito.

Tieni un diario

Mentre stai facendo pratica, spesso potresti avere in mente molte idee nuove ed eccitanti. Per esempio nuove direzioni musicali, nuovi suoni, nuove funzioni ecc. Queste idee a volte possono essere talmente interessanti che potresti fermarti e provare a realizzarle. Comunque, anche questa è una forma di distrazione!

Consiglio pratico n.8. Tieni un diario della tua pratica vicino alla tastiera. Quando hai delle idee che ti piacciono particolarmente, ferma un attimo la tua sessione di pratica e sbozza velocemente l’idea sul diario. Appena finito, dimenticatela e vai avanti con la sessione. Potrai quindi tornare indietro successivamente su quell’idea e pensarci con maggiore attenzione.

Mettiamo tutto insieme

Cerca di mettere a punto una routine di pratica che includa queste idee nel più gran numero possibile. Cerca di rendere le sessioni il più divertenti possibile ma sii sempre consapevole che alcune sessioni saranno dure e sentirai di aver svolto un lavoro insoddisfacente. Tuttavia, tutto ti sarà stato utile quando avrai creato il tuo primo brano o avrai eseguito il tuo primo concerto. Ricordati, la pratica è la chiave per il successo!


- Allungare i campioni

Quando le persone scoprono Sonic Pi, una delle prime cose che impara è quanto sia semplice riprodurre suoni pre-registrati usando la funzione sample. Ad esempio, puoi suonare un loop di tamburo industriale, ascoltare il suono di un coro o anche ascoltare un graffio di vinile tutto attraverso una singola riga di codice. Tuttavia, molte persone non si rendono conto che è possibile effettivamente variare la velocità, il campione viene riprodotto per alcuni effetti potenti e un nuovo livello di controllo sui suoni registrati. Quindi, scarica una copia di Sonic Pi e iniziamo a giocare con alcuni campioni!

Rallentare i campioni (samples)

Per modificare la frequenza di riproduzione di un campione dobbiamo utilizzare il rate: opt:

sample :guit_em9, rate: 1

Se si specifica un rate: di 1 allora il campione viene riprodotto alla velocità normale. Se vogliamo riprodurlo ad una velocità dimezzata, usiamo semplicemente una rate: di 0.5:

sample :guit_em9, rate: 0.5

Tieni conto che questo ha un duplice effetto sul suono. In primo luogo il campione suonerà più basso, più grave e in secondo luogo ci metterà il doppio ad essere riprodotto (dai un’occhiata alla barra laterale per una spiegazione più approfondita). Possiamo addirittura scegliere anche dei valori ancora più bassi avvicinandoci allo ‘0’. Per esempio ‘0.25’ è un quarto della velocità originale, ‘0.1’ è un decimo e così via. Prova a suonare i campioni utilizzando numeri bassi e osserva come puoi trasformare il suono in una specie di basso ruggito.

Accelerare i campioni

Oltre a prolungare ed abbassare i suoni mediante l’abbassamento del valore di rate, possiamo utilizzare dei valori più alti per accorciare e rendere più acuti i suoni. Proviamo a riprodurre un loop di batteria stavolta. Per prima cosa, prova ad ascoltare come suona alla velocità normale: ‘1’:

sample :loop_amen, rate: 1

Ora acceleriamoli un pò:

sample :loop_amen, rate: 1.5

Ha! We just moved musical genres from old-skool techno to jungle. Notice how the pitch of each drum hit is higher as well as how the whole rhythm speeds up. Now, try even higher rates and see how high and short you can make the drum loop. For example, if you use a rate of 100, the drum loop turns into a click!

Retromarcia

Ora, sono sicuro che molti di voi stanno pensando la stessa cosa adesso … “cosa succede se si utilizza un numero negativo per il rate?”. Grande domanda! Pensiamo a questo per un momento. Se il nostro rate: opt significa la velocità con cui viene riprodotto il campione, 1 è la velocità normale, 2 è doppia velocità, 0.5 è mezza velocità, -1 deve significare all’indietro! Proviamolo su un rullante. Innanzitutto, riprodurlo al ritmo normale:

sample :elec_filt_snare, rate: 1

Adesso fallo andare all’incontrario:

sample :elec_filt_snare, rate: -1

Of course, you can play it backwards twice as fast with a rate of -2 or backwards at half speed with a rate of -0.5. Now, play around with different negative rates and have fun. It’s particularly amusing with the :misc_burp sample!

Sample, Rate and Pitch

One of the effects of rate modification on samples is that faster rates result in the sample sounding higher in pitch and slower rates result in the sample sounding lower in pitch. Another place you may have heard this effect in every day life is when you’re cycling or driving past a beeping pedestrian crossing - as you’re heading towards the sound source the pitch is higher than when you’re moving away from the sound - the so-called Doppler effect. Why is this?

Let’s consider a simple beep which is represented by a sine wave. If we use an oscilloscope to plot a beep, we’ll see something like Figure A. If we plot a beep an octave higher, we’ll see Figure B and an octave lower will look like Figure C. Notice that the waves of higher notes are more compact and the waves of lower notes are more spread out.

A sample of a beep is nothing more than a lot of numbers (x, y, coordinates) which when plotted onto a graph will re-draw the original curves. See figure D where each circle represents a coordinate. To turn the coordinates back into audio, the computer works through each x value and sends the corresponding y value to the speakers. The trick here is that the rate at which the computer works through the x numbers does not have to be the same as the rate with which they were recorded. In other words, the space (representing an amount of time) between each circle can be stretched or compressed. So, if the computer walks through the x values faster than the original rate, it will have the effect of squashing the circles closer together which will result in a higher sounding beep. It will also make the beep shorter as we will work through all the circles faster. This is shown in Figure E.

Finally, one last thing to know is that a mathematician called Fourier proved that any sound is actually lots and lots of sine waves all combined together. Therefore, when we compress and stretch any recorded sound we’re actually stretching and compressing many sine waves all at the same time in exactly this manner.

Pitch Bending

As we’ve seen, using a faster rate will make the sound higher in pitch and a slower rate will make the sound lower in pitch. A very simple and useful trick is to know that doubling the rate actually results in the pitch being an octave higher and inversely halving the rate results in the pitch being an octave lower. This means that for melodic samples, playing it alongside itself at double/half rates actually sounds rather nice:

sample :bass_trance_c, rate: 1
sample :bass_trance_c, rate: 2
sample :bass_trance_c, rate: 0.5

However, what if we just want to alter the rate such that the pitch goes up one semitone (one note up on a piano)? Sonic Pi makes this very easy via the rpitch: opt:

sample :bass_trance_c
sample :bass_trance_c, rpitch: 3
sample :bass_trance_c, rpitch: 7

If you take a look at the log on the right, you’ll notice that an rpitch: of 3 actually corresponds to a rate of 1.1892 and a rpitch: of 7 corresponds to a rate of 1.4983. Finally, we can even combine rate: and rpitch: opts:

sample :ambi_choir, rate: 0.25, rpitch: 3
sleep 3
sample :ambi_choir, rate: 0.25, rpitch: 5
sleep 2
sample :ambi_choir, rate: 0.25, rpitch: 6
sleep 1
sample :ambi_choir, rate: 0.25, rpitch: 1

Mettiamo tutto insieme

Let’s take a look at a simple piece which combines these ideas. Copy it into an empty Sonic Pi buffer, hit play, listen to it for a while and then use it as a starting point for your own piece. See how much fun it is to manipulate the playback rate of samples. As an added exercise try recording your own sounds and play around with the rate to see what crazy sounds you can make.

live_loop :beats do
  sample :guit_em9, rate: [0.25, 0.5, -1].choose, amp: 2
  sample :loop_garzul, rate: [0.5, 1].choose
  sleep 8
end
 
live_loop :melody do
  oct = [-1, 1, 2].choose * 12
  with_fx :reverb, amp: 2 do
    16.times do
      n = (scale 0, :minor_pentatonic).choose
      sample :bass_voxy_hit_c, rpitch: n + 4 + oct
      sleep 0.125
    end
  end
end

- Additive Synthesis

This is the first of a short series of articles on how to use Sonic Pi for sound design. We’ll be taking a quick tour of a number of different techniques available for you to craft your own unique sound. The first technique we’ll look at is called additive synthesis. This may sound complicated - but if we expand each word slightly the meaning pops right out. Firstly, additive means a combination of things and secondly synthesis means to create sound. Additive synthesis therefore means nothing more complicated than combining existing sounds to create new ones. This synthesis technique dates back a very long time - for example, pipe organs in the middle ages had lots of slightly different sounding pipes which you could enable or disable with stops. Pulling out the stop for a given pipe ‘added it to the mix’ making the sound richer and more complex. Now, let’s see how we can pull out all the stops with Sonic Pi.

Simple Combinations

Let’s start with the most basic sound there is - the humble pure-toned sine wave:

synth :sine, note: :d3

Now, let’s see how this sounds combined with a square wave:

synth :sine, note: :d3
synth :square, note: :d3

Notice how the two sounds combine to form a new, richer sound. Of course, we don’t have to stop there, we can add as many sounds as we need. However, we need to be careful with how many sounds we add together. Just like when we mix paints to create new colours, adding too many colours will result in a messy brown, similarly - adding too many sounds together will result in a muddy sound.

Mescolare

Let’s add something to make it sound a little brighter. We could use a triangle wave at an octave higher (for that high bright sound) yet only play it at amp 0.4 so it adds something extra to the sound rather than taking it over:

synth :sine, note: :d3
synth :square, note: :d3
synth :tri, note: :d4, amp: 0.4

Now, try creating your own sounds by combining 2 or more synths at different octaves and amplitudes. Also, note that you can play around with each synth’s opts to modify each source sound before it is mixed in for even more combinations of sounds.

Detuning

So far, when combining our different synths we’ve used either the same pitch or switched octave. How might it sound if we didn’t stick to octaves but instead chose a slightly higher or lower note? Let’s try it:

detune = 0.7
synth :square, note: :e3
synth :square, note: :e3 + detune

If we detune our square waves by 0.7 notes we hear something that perhaps doesn’t sound in tune or correct - a ‘bad’ note. However, as we move closer to 0 it will sound less and less out of tune as the pitches of the two waves get closer and more similar. Try it for yourself! Change the detune: opt value from 0.7 to 0.5 and listen to the new sound. Try 0.2, 0.1, 0.05, 0. Each time you change the value, take a listen and see if you can hear how the sound is changing. Notice that low detune values such as 0.1 produce a really nice ‘thick’ sound, with both slightly different pitches interacting with each other in interesting, often surprising, ways.

:dsaw

Ampiezza

Another way we can finely craft our sound is to use a different envelope and options for each synth trigger. For example this will allow you to make some aspects of the sound percussive and other aspects ring out for a period of time.

detune = 0.1
synth :square, note: :e1, release: 2
synth :square, note: :e1 + detune, amp: 2, release: 2
synth :gnoise, release: 2, amp: 1, cutoff: 60
synth :gnoise, release: 0.5, amp: 1, cutoff: 100
synth :noise, release: 0.2, amp: 1, cutoff: 90

In the example above I have mixed in a noisy percussive element to the sound along with some more persistent background rumbling. This was achieved firstly by using two noise synths with middling cutoff values (90 and 100) using short release times along with a noise with a longer release time but with a low cutoff value (which makes the noise less crisp and more rumbly.)

Mettiamo tutto insieme

Let’s combine all these techniques to see if we can use additive synthesis to re-create a basic bell sound. I’ve broken this example into four sections. Firstly we have the ‘hit’ section which is the initial onset part of the bell sound - so uses a short envelope (e.g. a release: of around 0.1). Next we have the long ringing section in which I’m using the pure sound of the sine wave. Notice that I’m often increasing the note by roughly 12 and 24 which are the number of notes in one and two octaves. I have also thrown in a couple of low sine waves to give the sound some bass and depth. Finally, I used define to wrap my code in a function which I can then use to play a melody. Try playing your own melody and also messing around with the contents of the :bell function until you create your own crazy sound to play with!

define :bell do |n|
  # Triangle waves for the 'hit'
  synth :tri, note: n - 12, release: 0.1
  synth :tri, note: n + 0.1, release: 0.1
  synth :tri, note: n - 0.1, release: 0.1
  synth :tri, note: n, release: 0.2
  # Sine waves for the 'ringing'
  synth :sine, note: n + 24, release: 2
  synth :sine, note: n + 24.1, release: 2
  synth :sine, note: n + 24.2, release: 0.5
  synth :sine, note: n + 11.8, release: 2
  synth :sine, note: n, release: 2
  # Low sine waves for the bass
  synth :sine, note: n - 11.8, release: 2
  synth :sine, note: n - 12, release: 2
end
# Play a melody with our new bell!
bell :e3
sleep 1
bell :c2
sleep 1
bell :d3
sleep 1
bell :g2

- Subtractive Synthesis

This is the second in a series of articles on how to use Sonic Pi for sound design. Last month we looked at additive synthesis which we discovered was the simple act of playing multiple sounds at the same time to make a new combined sound. For example we could combine different sounding synths or even the same synth at different pitches to build a new complex sound from simple ingredients. This month we’ll look at a new technique commonly called subtractive synthesis which is simply the act of taking an existing complex sound and removing parts of it to create something new. This is a technique which is commonly associated with the sound of analog synthesisers of the 1960s and 1970s but also with the recent renaissance of modular analog synths through popular standards such as Eurorack.

Despite this sounding like a particularly complicated and advanced technique, Sonic Pi makes it surprisingly simple and easy - so let’s dive right in.

Complex Source Signal

For a sound to work well with subtractive synthesis, it typically needs to be fairly rich and interesting. This doesn’t mean we need something hugely complex - in fact, just a standard :square or :saw wave will do:

synth :saw, note: :e2, release: 4

Notice that this sound is already pretty interesting and contains many different frequencies above :e2 (the second E on a piano) which add to create the timbre. If that didn’t make much sense to you, try comparing it with the :beep:

synth :beep, note: :e2, release: 4

As the :beep synth is just a sine wave, you’ll hear a much purer tone and only at :e2 and none of the high crispy/buzzy sounds which you heard in the :saw. It’s this buzziness and variation from a pure sine wave that we can play with when we use subtractive synthesis.

Filtri

Once we have our raw source signal, the next step is to pass it through a filter of some kind which will modify the sound by removing or reducing parts of it. One of the most common filters used for subtractive synthesis is something called a low pass filter. This will allow all the low parts of the sound through but will reduce or remove the higher parts. Sonic Pi has a powerful yet simple to use FX system that includes a low pass filter, called :lpf. Let’s play with it:

with_fx :lpf, cutoff: 100 do
  synth :saw, note: :e2, release: 4
end

If you listen carefully you’ll hear how some of that buzziness and crispiness has been removed. In fact, all the frequencies in the sound above note 100 have been reduced or removed and only the ones below are still present in the sound. Try changing that cutoff: point to lower notes, say 70 and then 50 and compare the sounds.

Of course, the :lpf isn’t the only filter you can use to manipulate the source signal. Another important FX is the high pass filter referred to as :hpf in Sonic Pi. This does the opposite to :lpf in that it lets the high parts of the sound through and cuts off the low parts.

with_fx :hpf, cutoff: 90 do
  synth :saw, note: :e2, release: 4
end

Notice how this sounds much more buzzy and raspy now that all the low frequency sounds have been removed. Play around with the cutoff value - notice how lower values let more of the original bass parts of the source signal through and higher values sound increasingly tinny and quiet.

Low Pass Filter

:prophet

Filter Modulation

So far we’ve just produced fairly static sounds. In other words, the sound doesn’t change in any way for the entirety of its duration. Often you might want some movement in the sound to give the timbre some life. One way to achieve this is via filter modulation - changing the filter’s options through time. Luckily Sonic Pi gives you powerful tools to manipulate an FX’s opts through time. For example, you can set a slide time to each modulatable opt to specify how long it should take for the current value to linearly slide to the target value:

with_fx :lpf, cutoff: 50 do |fx|
  control fx, cutoff_slide: 3, cutoff: 130
  synth :prophet, note: :e2, sustain: 3.5
end

Let’s take a quick look at what’s going on here. Firstly we start an :lpf FX block as normal with an initial cutoff: of a very low 20. However, the first line also finishes with the strange |fx| at the end. This is an optional part of the with_fx syntax which allows you to directly name and control the running FX synth. Line 2 does exactly this and controls the FX to set the cutoff_slide: opt to 4 and the new target cutoff: to be 130. The FX will now start sliding the cutoff: opt’s value from 50 to 130 over a period of 3 beats. Finally we also trigger a source signal synth so we can hear the effect of the modulated low pass filter.

Mettiamo tutto insieme

This is just a very basic taster of what’s possible when you use filters to modify and change a source sound. Try playing with Sonic Pi’s many built-in FX to see what crazy sounds you can design. If your sound feels too static, remember you can start modulating the options to create some movement.

Let’s finish by designing a function which will play a new sound created with subtractive synthesis. See if you can figure out what’s going on here - and for the advanced Sonic Pi readers out there - see if you can work out why I wrapped everything inside a call to at (please send answers to @samaaron on Twitter).

define :subt_synth do |note, sus|
  at do
    with_fx :lpf, cutoff: 40, amp: 2 do |fx|
      control fx, cutoff_slide: 6, cutoff: 100
      synth :prophet, note: note, sustain: sus
    end
    with_fx :hpf, cutoff_slide: 0.01 do |fx|
      synth :dsaw, note: note + 12, sustain: sus
      (sus * 8).times do
        control fx, cutoff: rrand(70, 110)
        sleep 0.125
      end
    end
  end
end
subt_synth :e1, 8
sleep 8
subt_synth :e1 - 4, 8

- Creative coding in the classroom with Sonic Pi

(This article was published in issue 9 of the Hello World Magazine)

Code is one of the most creative media that humans have created. The initially obscure symbols of parentheses and lambdas are not just deeply rooted in science and mathematics, they are the closest we have managed to get to casting the same kind of magical spells as Gandalf and Harry Potter. I believe that this provides a powerful means of engagement in our learning spaces. Through the magic of code we are able to conjure up individually meaningful stories and learning experiences.

We are surrounded by magical experiences. From the sleight of hand of a stage magician making the ball disappear into thin air, to the wonder of seeing your favourite band perform on a big stage. It is these “wow” moments that inspire us to pick up a magic book and learn the French Drop or to start jamming power chords on an old guitar. How might we create similarly deep and lasting senses of wonder that will motivate people to practice and learn the fundamentals of programming?

Musical Engines and Notation

The histories of music and computers have been intricately woven together since the inception of computing machines, or “engines” as Charles Babbage’s powerful analytical engine was called. Back in 1842 the Mathematician Ada Lovelace, who worked very closely with Babbage, saw the creative potential of these engines. Whilst these first engines had originally been designed to accurately solve hard maths problems, Ada dreamt about making music with them:

”..the engine might compose elaborate and scientific pieces of music of any degree of complexity or extent.” Ada Lovelace, 1842.

Of course, today in 2019 much of our music, regardless of genre, has either been composed, produced or mastered with a digital computer. Ada’s dream came true. It is even possible to trace the history back even further. If you see coding as the art of writing sequences of special symbols that instruct a computer to do specific things, then musical composition is a very similar practice. In Western music, the symbols are black dots positioned on a stave of lines that tell the musician which notes to play and when. Intriguingly, if we trace the roots of Western music notation back to the Italian Benedictine monk, Guido d’Arezzo, we find that the dots and lines system that modern orchestras use is just one of a number of notation systems he worked on. Some of the others were much closer to what we might now see as code.

Get

Sonic Pi Performances

Programmare dal vivo

Sonic Pi has been used to perform in a wide range of venues such as school halls, nightclubs, outdoor stages at musical festivals, college chapels and prestigious music venues. For example the amazing Convo project which brought 1000 children together in the Royal Albert Hall to perform an ambitious new composition by composer Charlotte Harding. The piece was written for traditional instruments, choirs, percussion and Sonic Pi code. The pop-artist Jylda also performed with Sonic Pi in the Sage Gateshead for the Thinking Digital Conference, where she created a unique live-coded improvised remix of her song Reeled.

Sonic Pi in the Royal Albert Hall Sonic Pi used as one of the instruments as part of Convo at the Royal Albert Hall. Photo credit: Pete Jones.

Live coding in the classroom

Sonic Pi is a code-based music creation and performance tool that builds on all of these ideas. Unlike the majority of computing education software, it is both simple enough to use for education and also powerful enough for professionals. It has been used to perform in international music festivals, used to compose in a range of styles from classical, EDM and heavy metal, and was even reviewed in the Rolling Stone magazine. It has a diverse community of over 1.5 million live coders with a variety of backgrounds all learning and sharing their ideas and thoughts through the medium of code. It is free to download for Mac, PC and Raspberry Pi and includes a friendly tutorial that assumes you know nothing about either code or music.

Sonic Pi was initially conceived as a response to the UK’s newly released Computing curriculum in 2014. The goal was to find a motivating and fun way to teach the fundamentals of programming. It turns out that there is a lot in common and it’s huge fun to explain sequencing as melody, iteration as rhythm, conditionals as musical variety. I developed the initial designs and first iterations of the platform with Carrie Anne Philbin, who brought a teacher’s perspective to the project. Since then, Sonic Pi has undergone iterative improvements thanks to the feedback gained from observing learners and collaborating directly with educators in the classroom. A core design philosophy was to never add a feature that couldn’t be easily taught to a 10 year old child. This meant that most ideas had to be heavily refined and reworked until they were simple enough. Making things simple whilst keeping them powerful continues to be the hardest part of the project.

In order to provide the magical motivation, Sonic Pi’s design was never limited to a pure focus on education. Ideally there would be famous musicians and performers using Sonic Pi as a standard instrument alongside guitars, drums, vocals, synths, violins, etc. These performers would then act as motivational role models demonstrating the creative potential of code. For this to be possible sufficient focus and effort therefore had to be placed on making it a powerful instrument whilst still keeping it simple enough for 10 year olds to pick up. In addition to educators, I also worked directly with a variety of different artists in classrooms, art galleries, studios and venues in the early stages of Sonic Pi’s development. This provided essential feedback which enabled Sonic Pi to grow and ultimately flourish as a tool for creative expression.

There were a number of exciting and unexpected side effects of this dual focus on education and professional musicians. Many of the features are beneficial to both groups. For example, a lot of effort has been put into making error messages more friendly and useful (rather than being a huge complicated mess of jargon). This turns out to be very useful when you write a bug while performing in front of thousands of people. Additionally, functionality such as playing studio quality audio samples, adding audio effects, providing access to live audio from the microphone all turn out to make the learning experience more fun, rewarding and ultimately meaningful.

The Sonic Pi community continues to grow and share amazing code compositions, lesson plans, musical algorithms, and much more. Much of this happens on our friendly forum in_thread (in-thread.sonic-pi.net) which is home to a very diverse group of people that includes educators, musicians, programmers, artists and makers. It is a real joy to see people learn to use code to express themselves in new ways and for that in turn to inspire others to do the same.

- Some fun capabilities

From a Computer Science perspective, Sonic Pi provides you with the building blocks to teach you the basics as found in the UK’s curriculum such as sequencing, iteration, conditionals, functions, data structures, algorithms, etc. However, it also builds on a number of important and relevant concepts which have become adopted in mainstream industry such as concurrency, events, pattern matching, distributed computing and determinism - all whilst keeping things simple enough to explain to a 10 year old child.

Get

play 70

A melody can be constructed with one more command, sleep:

play 72
sleep 0.5
play 75
sleep 0.5
play 79

In this example, we play the note 70 (roughly the 70th note on a piano), wait for 1 second, play note 72, wait for half a second and then play note 75. What’s interesting here is that with just two commands we have access to pretty much all of Western notation (which notes to play and when) and learners can code any melody they’ve ever heard. This leads to huge variety in expressive outcomes whilst focussing on the same computing concept: sequencing in this case.

Taking ideas from the professional music world, we can also play back any recorded sound. Sonic Pi can play any audio file on your computer but also has a number of sounds built-in to make things easy to get started:

sample :loop_amen

This code will play back the drum break which was a pillarstone to early hip-hop, Drum and Bass and Jungle. For example, a number of early hip-hop artists played this drum break back at half speed to give it a more laid-back feeling:

sample :loop_amen, rate: 0.5

In the 90s a number of music scenes burst out of new technology which enabled artists to take drum breaks like this apart and reassemble in a different order. For example:

sample :loop_amen

rand


- Informazioni essenziali

Questa sezione copre alcune informazioni essenziali per ottenere il massimo da Sonic Pi.

Vedremo insieme le scorciatoie da tastiera che puoi utilizzare, come condividere il tuo lavoro e qualche consiglio su come esibirti con Sonic Pi.


10.1 - Utilizzare le scorciatoie

Sonic Pi è uno strumento così come è un ambiente di sviluppo. Le scorciatoie possono rendere l’esperienza di Sonic Pi più efficace e naturale, soprattutto se suoni live di fronte a un pubblico.

Sonic Pi può essere controllato in larga parte grazie alla tastiera. Familiarizzando con Sonic Pi, comincerai a utilizzare sempre di più le scorciatoie. Io suono con la tastiera (e vi consiglio di imparare a farlo) e mi ritrovo ad essere frustrato ogni volta che devo usare il mouse perché mi rallenta. Per questo uso queste scorciatoie regolarmente!

Se impari a utilizzare le scorciatoie, programmerai live come un professionista in men che non si dica.

Mi raccomando: non provare a impararli tutti in una volta, cerca di ricordare quelli che usi più spesso e di aggiungerne qualcuno a mano a mano che ti eserciti.

Coerenza tra le piattaforme

Immagina se stessi imparando a suonare il clarinetto. Ti aspetteresti che ogni clarinetto abbia gli stessi controlli e la stessa ditteggiatura. Se così non fosse, faresti fatica a suonare clarinetti diversi e saresti costretto a usarne soltanto uno.

Sfortunatamente ci sono tre sistemi operativi principalmente: Linux, Max OSX e Windows che hanno le loro funzioni standard per azioni come taglia e incolla, ecc… Sonic Pi cerca di rispettare questi standard. Tuttavia la priorità è mantenere una coerenza tra le piattaforme all’interno di Sonic Pi invece che adattarsi agli standard di ciascuna piattaforma. Questo significa che quando impari le scorciatoie usando Sonic Pi sul tuo Raspberry Pi, puoi spostarti su Mac o PC e sentirti a casa.

Controllo e Meta

La prima parte relativa alla coerenza è relativa ai nomi delle abbreviazioni. In Sonic Pi usiamo i nome Controllo e Meta per fare riferimento a due combinazioni di tasti. Su tutte le piattaforme Controllo è lo stesso invece su Linux e Windows Meta è il tasto Alt mentre su Mac Meta è il tasto Command. Per coerenza useremo il termina Meta, ricordati solo di mapparlo nel modo corretto con la tastiera del tuo sistema operativo.

Abbreviazioni

Per semplicità utilizzeremo delle abbreviazioni C- per Controllo e M- per Meta. Per esempio se per una scorciatoia devi tenere premuti contemporaneamente Meta e r noi scriveremo M-r. Il - indica “premi insieme.”

Questi sono alcune delle scorciatoie più utili.

Fermarsi e ripartire

Invece che andare alla ricerca del mouse per far funzionare il tuo codice, puoi premere M-r. Allo stesso modo, per fermare premi M-s.

Io mi sento davvero perso senza le scorciatoie di navigazione. Per questo ti consiglio di investire parte del tuo tempo per impararle. Queste scorciatoie funzionano molto bene quando vuoi muoverti solo utilizzando la tastiera invece che muovendo il mouse o le frecce sulla tastiera.

Puoi muoverti all’inizio della riga con C-a, alla fine della riga con C-e, alla riga precedente C-p oppure su quella successiva C-n, avanti di un carattere C-f oppure indietro di uno C-b. Puoi anche eliminare tutti i caratteri partendo dalla posizione del cursore fino alla fine della riga con C-k.

Codice più pulito

Per allineare automaticamente il codice, premi semplicemente ‘M-m’.

Sistema di aiuto

Per aprire il pannello di aiuto, puoi premere M-i. Tuttavia è importante conoscere anche la scorciatoia C-i che ti aiuta a trovare nella documentazione la parola che si trova sotto il cursore per un aiuto immediato!

Per una lista completa, dai un’occhiata alla sezione 10.2 con il riassunto di tutte le scorciatoie.


10.2 - Riassunto scorciatoie

Quello che segue è un riassunto delle principali scorciatoie disponibili in Sonic Pi. Dai un’occhiata alla sezione 10.1 per avere un background in merito.

Convenzioni

In questa lista vengono usate le seguenti convenzioni (dove Meta è Alt su Windows/Linux o Cmd su Mac):

C-a significa tieni premuto Control e il tasto a contemporaneamente. M-r significa tieni premuti il tasto Meta e poi premi r. S-M-z vuol dire premi contemporaneamente Shift, Meta e il tasto z. C-M-f significa premi Control, Meta e f contemporaneamente.

Controllo dell’applicazione principale

M-r - Avvia il codice M-s - Ferma il codice M-i - Apri/Chiudi il sistema di aiuto M-p - Apri/Chiudi le preferenze M-{ - Sposta il buffer a sinistra M-} - Sposta il buffer a destra M-+ - Ingrandisci la dimensione carattere del buffer corrente M-- - Diminuisci la grandezza dei caratteri nel buffer corrente

Selezione/Copia/Incolla

M-a - Seleziona tutto M-c - Copia M-] - Copia M-x - Taglia C-] - Taglia C-k - Taglia fino alla fine della riga M-v - Incolla C-y - Incolla C-SPACE - Imposta un segnalibro. La navigazione controllerà la regione selezionata. Premi C-g per uscire.

Controllo del testo

M-m - Allinea il testo Tab - Allinea la linea corrente (oppure seleziona l’autocompletamento) C-l - Centra l’editor M-/ - Commenta/Scommenta la linea corrente C-t - Trasponi/scambia caratteri M-u - Converti la parola successiva in maiuscolo. M-l - Converti la parola successiva in minuscolo.

C-a - Spostati all’inizio della riga C-e - Spostati alla fine della riga C-p - Spostati alla linea precedente C-n - Spostati su quella successiva C-f - Spostati avanti di un carattere C-b - Spostati indietro di un carattere M-f - Spostati avanti di una parola M-b - Spostati indietro di una parola C-M-n - Sposta linea o selezione in basso C-M-p - Sposta linea o selezione in alto S-M-u - Spostati in su di 10 righe S-M-d - Spostati in giù di 10 righe M-< - Spostati all’inizio del buffer M-> - Spostati alla fine del buffer

Cancellazione

C-h - Cancella il carattere precedente C-d - Cancella il carattere successivo

Caratteristiche avanzate dell’Editor

‘C-i’ - Mostra i documenti collegati alla parola dove si trova il cursore ‘M-z’ - Annulla ‘S-M-z’ - Torna indietro dopo l’annullamento ‘C-g’ - Esci ‘S-M-f - Avvia la modalità a schermo intero ‘S-M-b’ - Attiva la visibilità dei bottoni ‘S-M-l’ - Rende visibile la finestra di log ‘S-M-m’ - Passa dall’interfaccia scura a quella chiara e viceversa S-M-s - Salva il contenuto del buffer in un file S-M-o - Carica il contenuto del buffer da un file


10.3 - Condivisione

Sonic Pi è molto incentrato sulla condivisione e sull’apprendimento in compagnia.

Una volta che avrai imparato a codificare la musica, condividere le tue composizioni sarà semplice come mandare delle email contenenti il tuo programma. Per favore, condividi il tuo codice con gli altri in modo tale da fagli imparare dal tuo lavoro e anche riutilizzarne delle parti all’interno di nuovi brani.

Se non sai quale sia il modo migliore per condividere il tuo lavoro con gli/le altri/e, ti consiglio di metterlo su GitHub. La tua musica invece può essere messa su SoundCloud. In questo modo potrai raggiungere facilmente un pubblico molto vasto.

Codice -> GitHub

GitHub è un sito per condividere e lavorare sul codice. E’ utilizzato da sviluppatori professionisti ma anche da artisti per condividere e collaborare. Il modo più semplice per condividere un nuovo programma (anche un brano non completo) è quello di creare una Gist. Gist è un modo facile di caricare il tuo codice in un modo che gli altri possano vederlo, copiarlo e condividerlo a loro volta.

Musica -> SoundCloud

Un altro modo in cui puoi condividere il tuo lavoro è di registrare l’audio e di caricarlo su SoundCloud. Una volta che avrai caricato il tuo brano, gli altri utenti possono commentarlo. Ti raccomando di mettere un collegamento al tuo Gist nella descrizione del brano.

Per registrare il tuo lavoro, premi il tasto ‘Rec’ in alto e la registrazione comincerà immediatamente. Premi anche ‘Run’ per iniziare a suonare, se non l’hai già fatto. Quando hai finito di registrare, basta semplicemente premere nuovamente il bottone lampeggiante ‘Rec’ e ti apparirà una piccola finestra per inserire il nome desiderato. Il brano sarà salvato in formato WAV, che poi può essere modificato e convertito in MP3. Ci sono molti programmi validi e gratuiti per far questo (prova Audacity per esempio).

Speranza

Ti incoraggio a condividere il tuo lavoro e spero veramente che riusciremo a insegnarci l’un l’altro nuove scorciatoie e tecniche per utilizzare Sonic Pi. Sono molto ansioso di vedere cosa mi vorrai mostrare.


10.4 - Suonare dal vivo

Uno degli aspetti più eccitanti di Sonic Pi è che ti permette di usare il codice come uno strumento musicale. Questo significa che scrivere codice live può essere visto come un modo nuovo di esibirsi.

Noi lo chiamiamo Live Coding.

Mostra lo schermo

Quando programmi live, ti consiglio di mostrare lo schermo al tuo pubblico. Altrimenti sarebbe come suonare la chitarra nascondendo le dita. Quando faccio pratica, uso un Raspberry Pi con collegato un piccolo proiettore in salotto. Puoi usare la TV o un proiettore per fare il tuo show. Provaci, è molto divertente.

Forma una band

Don’t just play on your own - form a live coding band! It’s a lot of fun jamming with others. One person could do beats, another ambient background, etc. Use the live_audio functionality to combine code with traditional instruments such as a guitar or a microphone.

See what interesting combinations of sounds you can create with code.

TOPLAP

La programmazione live non è un concetto nuovo: un piccolo gruppo di persone lo fa da anni (usando sistemi costruiti su misura). Un ottimo posto per scoprire di più è TOPLAP.

Algorave

Un’altra importante risorsa per esplorare il live coding è il mondo degli Algorave. Sul sito puoi trovare tutte le informazioni su eventi di live coding in locali.


- Minecraft Pi

Sonic Pi ora supporta un’API semplice che permette di interfacciarsi con Minecraft Pi, una versione speciale di Minecraft che è installata di default sul sistema operativo Raspbian Linux sul Rasberry Pi.

Non è necessario importare librerie

L’integrazione con Minecraft Pi è stata pensata per essere estremamente semplice da usare. Tutto quello che devi fare è lanciare Minecraft Pi e creare un mondo. Sarai libero di usare le funzioni mc_* esattamente come usi playe synth. Non è necessario importare nient’altro né installare librerie. È tutto pensato per funzionare all’avvio.

Correzione automatica

L’API di Minecraft si prenderà cura di tutte le connessioni all’applicazione Minecraft Pi. Questo significa che non è necessario preoccuparsi di queste cose. Se provi a usare l’API Minecraft Pi senza aver aperto Minecraft PI, Sonic Pi te lo dirà. Allo stesso modo, se chiudi Minecraft Pi mentre stai ancora riproducendo un live_loop che usa l’API, il loop si fermerà e ti dirà che non può più connettersi. Per riconnettersi, apri di nuovo Minecraft Pi e Sonic Pi ricreerà automaticamente la connessione per te.

Pensato per essere programmato dal vivo

L’API Minecraft Pi è stata pensata per lavorare senza problemi con i live_loop. Questo significa che è possibile sincronizzare le modifiche nel tuo mondo Minecraft Pi con le modifiche fatte nei suoni di Sonic Pi. Video musicali basati su Minecraft realizzati istantaneamente! Attenzione, però, Minecraft Pi è ancora in alpha e potrebbe avere qualche bug. Se riscontri dei problemi, prova a riavviare Minecraft Pi. Sonic Pi ristabilirà automaticamente la connessione.

Richiedere un Raspberry Pi 2.0

È fortemente consigliato usare un Raspberry Pi 2 se vuoi utilizzare contemporaneamente Sonic Pi e Minecraft allo stesso tempo, specialmente se vuoi usare le possibilità sonore di Sonic Pi.

Supporto API

A questo punto Sonic Pi supporta modifiche ai blocchi e al player come descritto nella sezione 11.1. Il supporto per il callback degli evneti lanciati dal player è pianificato per una release futura.


11.1 - API di base di Minecraft Pi

Sonic Pi attualmente supporta le seguenti interazioni con Minecraft Pi:

Mostrare i messaggi della chat Impostare la posizione dell’utante Ricevere la posizione dell’utente Impostare il tipo di blocco a una coordinata specifica Ricevere il tipo di blocco a una coordinata specifica

Diamo un’occhiata a ognuna di esse, una alla volta.

Mostrare i messaggi della chat

Per prima cosa, guardiamo come sia semplice controllare Minecraft Pi da Sonic Pi. Assicurati di avere Minecraft Pi e Sonic Pi aperti e di essere entrato in un mondo di Minecraft.

In un buffer di Sonic Pi, inserisci il seguente codice:

mc_message "Hello from Sonic Pi"

Quando premi Run vedrai comparire un messaggio nella finestra di Minecraft. Congratulazioni! Hai scritto il tuo primo codice Minecraft. Semplice, no?

Impostare la posizione dell’utante

Ora, proviamo con un po’ di magia. Usiamo il teletrasporto! Prova con il seguente codice:

mc_teleport 50, 50, 50

Quando premi Run, boom! Sei stato teletrasportato in un luogo nuovo. Probabilmente era da qualche parte nel cielo e sei caduto in terra o nell’acqua. Ragioniamo: cosa sono quei numeri 50, 50, 50? Sono le coordinate del luogo verso cui stiamo cercando di teletrasportarci. Prendiamoci un momento per capire come funzionano le coordinate perché sono molto importanti in Minecraft.

Coordinate

Immagina una mappa dei pirati con una grande X a segnalare il luogo del tesoro. L’esatta posizione di X può essere descritta con due numeri: la posizione da destra a sinistra e quella dal basso verso l’alto. Per esempio 10cm orizzontalmente e 8cm in verticale. Questi due numeri: 10 e 8 sono coordinate. Puoi immaginare di descrivere il luogo dove si trovano altri pezzi del tesoro con altre paia di numeri. Ad esempio può esserci un secchio di oro a 2 orizzontale e 9 verticale…

Ora, in Minecraft due numeri non bastano. Dobbiamo anche sapere la profondità per cui ci servono tre numeri:

Quanto da destra a sinistra: x Quanto in profondità: z E quanto in alto: y

Un’ultima cosa, di solito scriviamo queste coordinate in quest’ordine: x, y, z.

Trovare le tue coordinate

Proviamo a giocare con le coordinate. Naviga in un punto della mappa di Minecraft e apri Sonic Pi. Ora, inserisci questo codice:

puts mc_location

Quando premi il pulsante Run vedrai le coordinate della tua posizione corrente mostrate nella finestra di log. Prendi nota. Muoviti nel mondo e prova di nuova. Guarda come sono cambiate. Ti consiglio di fare qualche prova in più, ripetendo gli stessi passaggi: muoviti in giro, guarda le coordinate e ripeti. Fallo finché non ti senti a tuo agio su come cambiano i valori quando ti muovi. Una volta capito come funzionano, sarà semplicissimo usare l’API Minecraft.

Costruiamo!

Ora che sai come trovare le tue coordinate e come teletrasportarti, hai tutti gli strumenti a disposizione per costruire qualcosa in Minecraft. Facciamo finta che tu voglia costruire un blocco di vetro alle seguenti coordinate: 40, 50, 60. È molto semplice:

mc_set_block :glass, 40, 50, 60

Semplice, no? Per vedere il risultato, teletrasportati nelle vicinanze:

mc_teleport 35, 50, 60

Ora guardati intorno, dovresti vedere un blocco di vetro! Proviamo a cambiarlo in diamante:

mc_set_block :diamond, 40, 50, 60

Se stavi guardando nella giusta direzione, forse l’hai visto cambiare direttamente con i tuoi occhi. Questo è l’inizio di qualcosa di eccitante…

Guardare i blocchi

Prendiamo in esame un’ultima cosa prima di andare avanti con qualcosa di più complesso. Dato un set di coordinate, possiamo chiedere a Minecraft la tipologia del blocco. Proviamolo con il blocco di diamante che abbiamo appena creato:

puts mc_get_block 40, 50, 60

Evviva! Dice :diamond. Prova a cambiarlo di nuovo in vetro e a rifare la richiesta. Ora dice :glass, giusto? Sono sicuro che lo fa :-)

Tipi di blocco disponibili

Prima di andare avanti con Minecraft Pi, eccoti una lista delle tipologie di blocchi disponibili:

    :air
    :stone
    :grass
    :dirt
    :cobblestone
    :wood_plank
    :sapling
    :bedrock
    :water_flowing
    :water
    :water_stationary
    :lava_flowing
    :lava
    :lava_stationary
    :sand
    :gravel
    :gold_ore
    :iron_ore
    :coal_ore
    :wood
    :leaves
    :glass
    :lapis
    :lapis_lazuli_block
    :sandstone
    :bed
    :cobweb
    :grass_tall
    :flower_yellow
    :flower_cyan
    :mushroom_brown
    :mushroom_red
    :gold_block
    :gold
    :iron_block
    :iron
    :stone_slab_double
    :stone_slab
    :brick
    :brick_block
    :tnt
    :bookshelf
    :moss_stone
    :obsidian
    :torch
    :fire
    :stairs_wood
    :chest
    :diamond_ore
    :diamond_block
    :diamond
    :crafting_table
    :farmland
    :furnace_inactive
    :furnace_active
    :door_wood
    :ladder
    :stairs_cobblestone
    :door_iron
    :redstone_ore
    :snow
    :ice
    :snow_block
    :cactus
    :clay
    :sugar_cane
    :fence
    :glowstone_block
    :bedrock_invisible
    :stone_brick
    :glass_pane
    :melon
    :fence_gate
    :glowing_obsidian
    :nether_reactor_core