Sei sulla pagina 1di 245

Inventare il suono con

PURE DATA
Manuale introduttivo di musica elettronica
vers. 0.4.3

Francesco Bianchi
elettrochuck@gmail.com

2013
a Mina,
per il suo amore e il suo sostegno
N OTA SUL C OPYRIGHT

Questo documento e il suo contenuto sono rilasciati sotto licenza Creative


Commons 2.5 di tipo Attribuzione-Non commerciale-Condividi allo stesso
modo 2.5 Generico.

Sei quindi libero:

• di riprodurre, distribuire, comunicare al pubblico, esporre in pub-


blico, rappresentare, eseguire e recitare quest’opera

• di modificare quest’opera

alle seguenti condizioni:

• Attribuzione. Devi attribuire la paternità dell’opera nei modi indi-


cati dall’autore o da chi ti ha dato l’opera in licenza e in modo tale
da non suggerire che essi avallino te o il modo in cui tu usi l’opera.

• Non commerciale. Non puoi usare quest’opera per fini commerciali.

• Condividi allo stesso modo. Se alteri o trasformi quest’opera, o se


la usi per crearne un’altra, puoi distribuire l’opera risultante solo con
una licenza identica o equivalente a questa.

2
CONTENTS

Introduzione 9

i l’ambiente 10
1 fondamenti 11
1.1 Cos’è Pure Data? . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2 Pd-extended . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3 Installazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3.1 GNU/Linux . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3.2 Windows e Mac Os X . . . . . . . . . . . . . . . . . . . 13
2 panoramica dell’ambiente 14
2.1 Pd window e patch window . . . . . . . . . . . . . . . . . . . . . 14
2.1.1 il motore DSP . . . . . . . . . . . . . . . . . . . . . . . . 15
2.1.2 print . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.2 Le scatole di Pd . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.2.1 oggetti e connessioni . . . . . . . . . . . . . . . . . . . . 16
2.2.2 messaggi e liste . . . . . . . . . . . . . . . . . . . . . . . 18
bang e number box . . . . . . . . . . . . . . . . . . . . . . 19
3 basi di programmazione con pure data 21
3.1 Variabili e costanti . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.1.1 pack e unpack . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.2 Gestione del tempo . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.2.1 metro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
un contatore . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.2.2 line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.2.3 delay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.2.4 line multirampa con delay . . . . . . . . . . . . . . . . . 29
3.3 Aritmetica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.3.1 operatori aritmetici . . . . . . . . . . . . . . . . . . . . . 29
3.3.2 expr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.4 Generatori di numeri casuali . . . . . . . . . . . . . . . . . . . 32
3.5 Connessioni senza cavi . . . . . . . . . . . . . . . . . . . . . . . 34
3.6 Subpatches e Abstractions . . . . . . . . . . . . . . . . . . . . . . 34
3.6.1 subpatch . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.6.2 abstraction . . . . . . . . . . . . . . . . . . . . . . . . . . 38

3
3.6.3 graph on parent . . . . . . . . . . . . . . . . . . . . . . . 39
4 vettori, grafici e tabelle 41
4.1 Vettori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.1.1 leggere un vettore . . . . . . . . . . . . . . . . . . . . . 46
4.1.2 l’oggetto table . . . . . . . . . . . . . . . . . . . . . . . . 46
5 programmazione avanzata 48
5.1 Istruzioni condizionali . . . . . . . . . . . . . . . . . . . . . . . 48
5.1.1 operatori relazionali . . . . . . . . . . . . . . . . . . . . 48
5.1.2 select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.1.3 operatori logici . . . . . . . . . . . . . . . . . . . . . . . 51
5.1.4 If . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.2 loops e iterazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6 il midi 58
6.1 Panoramica sul protocollo MIDI . . . . . . . . . . . . . . . . . 58
6.1.1 anatomia di un messaggio MIDI . . . . . . . . . . . . . 59
6.2 Pd e il MIDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
6.2.1 midiin e midianalyze . . . . . . . . . . . . . . . . . . . . 61
6.2.2 altri oggetti MIDI . . . . . . . . . . . . . . . . . . . . . . 63
6.3 Un esempio di editing algoritmico MIDI . . . . . . . . . . . . 64
7 oggetti gui 71
7.1 Altre GUI dalle librerie di Pd . . . . . . . . . . . . . . . . . . . 75

ii audio 76
8 l’audio digitale 77
8.1 L’oscillatore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
8.1.1 frequenza e ampiezza del segnale . . . . . . . . . . . . 79
8.1.2 osc∼ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
8.1.3 tabwrite∼ . . . . . . . . . . . . . . . . . . . . . . . . . . 84
8.1.4 la rappresentazione del suono . . . . . . . . . . . . . . 84
8.2 Le forme d’onda . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
8.2.1 tabosc4∼ . . . . . . . . . . . . . . . . . . . . . . . . . . 87
8.2.2 onda quadra . . . . . . . . . . . . . . . . . . . . . . . . . 88
pulse width modulation (PWM) . . . . . . . . . . . . . 90
8.2.3 onda a dente di sega . . . . . . . . . . . . . . . . . . . . 92
phasor∼ . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
8.2.4 onda triangolare . . . . . . . . . . . . . . . . . . . . . . 94
9 il panning 99
9.1 l’oggetto dac∼ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

4
9.2 Controllo del panning . . . . . . . . . . . . . . . . . . . . . . . . 100
9.2.1 Segnali bipolari e unipolari . . . . . . . . . . . . . . . . 102
9.2.2 il DC offset . . . . . . . . . . . . . . . . . . . . . . . . . 102
10 sintesi additiva e sintesi vettoriale 106
10.1 Sintesi additiva . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
10.1.1 sintesi additiva a spettro armonico . . . . . . . . . . . . 106
10.1.2 sintesi additiva a spettro non armonico . . . . . . . . . 106
10.2 Sintesi vettoriale . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
10.2.1 dissolvenza incrociata fra due tabelle . . . . . . . . . . 109
10.2.2 dissolvenza incrociata fra quattro tabelle . . . . . . . . 110
11 sintesi sottrattiva 114
11.1 La sintesi sottrattiva . . . . . . . . . . . . . . . . . . . . . . . . 114
11.1.1 il rumore . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
11.2 I filtri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
11.3 I parametri dei filtri . . . . . . . . . . . . . . . . . . . . . . . . . 121
11.4 I filtri in pd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
11.5 Il filtro vcf∼ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
11.6 Un sequencer con vcf∼ e samphold∼ . . . . . . . . . . . . . . . 126
12 moulazione ad anello (rm), tremolo, modulazione d’ampiezza
(am) 128
12.1 La modulazione ad anello . . . . . . . . . . . . . . . . . . . . . 128
12.2 Segnali bipolari e unipolari . . . . . . . . . . . . . . . . . . . . 130
12.3 Segnale di controllo dell’ampiezza: il tremolo . . . . . . . . . 131
12.4 La modulazione d’ampiezza . . . . . . . . . . . . . . . . . . . . 135
12.4.1 l’indice di modulazione . . . . . . . . . . . . . . . . . . 137
13 vibrato e modulazione di frequenza (fm) 142
13.1 Segnale di controllo della frequenza: il vibrato . . . . . . . . . 142
13.2 Modulazione di frequenza . . . . . . . . . . . . . . . . . . . . . 143
13.2.1 l’inviluppo . . . . . . . . . . . . . . . . . . . . . . . . . . 145
13.2.2 FM a spettro variabile . . . . . . . . . . . . . . . . . . . 148
13.3 Portanti multiple . . . . . . . . . . . . . . . . . . . . . . . . . . 150
13.4 Modulanti multiple . . . . . . . . . . . . . . . . . . . . . . . . . 152
14 introduzione alla sintesi granulare 157
14.1 Teoria della sintesi granulare . . . . . . . . . . . . . . . . . . . 157
14.1.1 dipendenza vs. indipendenza dei parametri . . . . . . 157
14.1.2 overlapping . . . . . . . . . . . . . . . . . . . . . . . . . 159
14.1.3 parametri e spettri risultanti . . . . . . . . . . . . . . . 162
14.1.4 Il dominio del tempo e la sintesi granulare . . . . . . . 164

5
14.2 Implementazione in pd . . . . . . . . . . . . . . . . . . . . . . . 166
14.3 Un esempio di Trainlet Synthesis . . . . . . . . . . . . . . . . . . 166
14.4 La Pulsar Synthesis . . . . . . . . . . . . . . . . . . . . . . . . . 167
14.5 Asyncronous Granular Synthesis . . . . . . . . . . . . . . . . . . 170
14.5.1 vline∼ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
14.5.2 rendere indipendente il parametro gdur . . . . . . . . . 176
14.6 Granulazione con suoni campionati . . . . . . . . . . . . . . . 182
15 lavorare con sorgenti audio esterne 185
15.1 Sintesi vs. campioni . . . . . . . . . . . . . . . . . . . . . . . . . 185
15.2 Alcuni oggetti utili . . . . . . . . . . . . . . . . . . . . . . . . . 185
15.3 Un semplice random slicer . . . . . . . . . . . . . . . . . . . . . 187
15.3.1 controllare lo slicer via segnale . . . . . . . . . . . . . . 191
15.4 Granulazione su files audio . . . . . . . . . . . . . . . . . . . . 195

iii applicazioni varie 202


16 estendibilità di pd 203
16.1 pd come linguaggio di programmazione . . . . . . . . . . . . 203
16.1.1 externals e librerie . . . . . . . . . . . . . . . . . . . . . . 203
16.1.2 alcune librerie . . . . . . . . . . . . . . . . . . . . . . . . 204
17 gem e il video 205
17.1 la libreria GEM . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
17.2 interazione audio e GEM . . . . . . . . . . . . . . . . . . . . . . 208
18 networking 213
18.1 Architettura di rete in Pd . . . . . . . . . . . . . . . . . . . . . 213
18.1.1 netsend e netreceive . . . . . . . . . . . . . . . . . . . . . 214
18.1.2 Dynamic patching . . . . . . . . . . . . . . . . . . . . . . 217
18.1.3 pdsend . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
18.2 il protocollo OSC . . . . . . . . . . . . . . . . . . . . . . . . . . 223
18.3 L’audio in streaming . . . . . . . . . . . . . . . . . . . . . . . . . 225
19 applicazioni sparse 233
19.1 Laptop Orchestra . . . . . . . . . . . . . . . . . . . . . . . . . 233
19.2 Il Live Coding . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
19.3 Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Conclusione 239
Bibliografia 241
Sitografia 242
Indice analitico 243

6
INTRODUZIONE

La diffusione massiccia che i moderni calcolatori hanno avuto negli ultimi


30 anni ha prodotto un’onda d’urto dirompente nel mondo della musica
elettronica che fino agli anni ’70 era appannaggio di quei pochi fortunati
che potevano accedere ai rari centri europei e americani che disponevano
delle apparecchiature per realizzarla. In pochi anni, a partire dall’avvento
dei primi home computers si sono moltiplicati a dismisura i software di ma-
nipolazione dell’audio e oggi chiunque può trovare in rete o in commer-
cio programmi per produrre il proprio brano o il proprio disco di musica
elettronica, spesso senza il bisogno di conoscere a fondo i principi, il fun-
zionamento e le tecniche che stanno alla base dell’audio digitale. Con un
semplice click è possibile proiettarsi nel mondo dei suoni più strani senza
dover necessariamente conoscere una tecnica di sintesi o, quantomeno, un
oscillatore.

Stando così le cose, qualcuno a questo punto potrebbe chiedersi, leggitti-


mamente, perché dovrebbe leggere un manuale di musica elettronica. Il
panorama del software è talmente vasto che chiunque può trovare il pro-
gramma adatto alle sue esigenze, in linea con le proprie conoscenze infor-
matiche e musicali. Eppure ci sono varie ragioni perché si potrebbe leggere
un manuale del genere e imparare almeno le basi della programmazione e
della sintesi dell’audio. Proviamo ad elencarne qualcuna:

- Studiare la musica elettronica aiuta a capire meglio quello che si fa


con i programmi, soprattutto aiuta a capire quali sono i limiti dei
programmi stessi. Ad esempio i sintetizzatori software attualmente
in commercio sono per lo più monofunzionali, cioè svolgono un com-
pito e solo quello. Naturalmente in molti casi lo svolgono benissimo,
ma non sanno fare altro. Ci sono sintetizzatori per la Modulazione
di Frequenza, sintetizzatori per la Sintesi Granulare o Additiva. Se si
vuole possedere un sintetizzatore per una di queste tecniche bisogna
acquistarlo o bisogna accontentarsi di prodotti che non danno ottimi
risultati.

7
- Questi programmi costano molto, soprattutto i migliori. Se si vo-
lessero avere dei sintetizzatori per realizzare 3 o 4 tecniche di sintesi
del suono si dovrebbero acquistare 3 o 4 prodotti commerciali di-
versi, questo a scapito del portafogli e del fatto che probabilmente fra
qualche anno saranno obsoleti e diverranno quindi praticamente inu-
tili. E’ molto meglio studiare le tecniche di sintesi e il funzionamento
dell’audio digitale per avere l’opportunità di utilizzare programmi
forse più complessi, ma che danno l’opportunità di costruirsi da soli
i propri suoni.

- Inventare i propri suoni non è una cosa da poco. I software commer-


ciali sono corredati sempre da moltissimi suoni preconfezionati, detti
preset, molto utili, ma che affievoliscono inevitabilmente il desiderio
di cercarne di nuovi. Si inizia ad accontentarsi di quello che offre il
convento, che spesso è gradevole e non richiede dispendio eccessivo
di energie. Ma quei suoni saranno sempre dei preset fatti da qualcun
altro, non apparterranno mai completamente a chi li usa. Quindi stu-
diare e praticare la musica elettronica è un modo per appropriarsi
del suono, per creare il proprio, che molte volte non sarà il più bello,
ma alcune volte sarà sicuramente unico.

- Un ultimo argomento, ma non certo meno importante. Una volta


apprese le tecniche di sintesi si possono scegliere programmi a costo
zero, cioè freeware, come Pure Data, oggetto di questo manuale. Scegliere
un programma gratuito implica molte cose, alcune meno scontate di
quanto si pensi:
– Non è solo una scelta di risparmio, ma una rivendicazione etica.
Sintetizzare il suono attraverso un software digitale implica la
progettazione e la realizzazione di algoritmi più o meno com-
plessi. Gli algoritmi non sono altro che rappresentazioni del
pensiero, e il pensiero non si paga, nessun prezzo.
– Usare un software libero significa condividerne una filosofia
basata sulla condivisione dei saperi. I programmi liberi sono
tali in tutto e per tutto nella maggior parte dei casi. Si può prel-
evare il sorgente, studiarlo, modificarlo e redistribuirlo. Non a
caso intorno a questi software ci sono delle vere e proprie comu-
nità che si scambiano opinioni, idee e progetti, condividendo
liberamente il proprio pensiero con altri.

8
– Il software libero è soggetto a mutamento continuo, a un divenire
costante che lo pone nella condizione di migliorare molto più
velocemente del software commerciale e di non invecchiare mai.

Studiate quindi la musica elettronica e praticatela, possibilmente con soft-


ware libero.

Buon divertimento!

9
Part I

L’A M B I E N T E
1 FONDAMENTI

1.1 C OS ’ È P URE D ATA ?

Traducendo dal sito ufficiale, apprendiamo che Pure Data è un ambiente di


programmazione grafica in tempo reale per processare audio e video1 . Cer-
chiamo di entrare nel dettaglio di questa descrizione. Pure Data è prima
di tutto un linguaggio di programmazione perché consente di realizzare al-
goritmi più o meno complessi come tutti gli altri linguaggi2 . L’interfaccia
con cui il musicista-programmatore parla con Pd è grafica, quindi non c’è
la necessità di scrivere il codice in un editor di testo, ma si realizzano delle
patch combinando fra loro vari tipi di oggetti grafici. Nel gergo dei sinte-
tizzatori analogici una patch rappresentava l’insieme dei collegamenti fra i
suoi moduli. Pd mutua questo concetto: attraverso una patch si definisce
graficamente l’ordine con cui i vari oggetti sono collegati fra loro. Gli al-
goritmi vengono creati selezionando una serie di entità grafiche all’interno
di una finestra, detta patch window.

Pd funziona in tempo reale, quindi gli algoritmi sono interattivi e i parametri


possono essere modificati durante l’esecuzione. E’ anche possibile cam-
biare la struttura stessa di tali algoritmi mentre sono attivi, aggiungendo o
rimuovendo moduli in modo semplice e intuitivo.

Pd nasce con la funzione di creare applicazioni audio e, da qualche tempo,


video. Una foltissima comunità di sviluppatori, musicisti, hackers e appas-
sionati sforna ogni giorno nuove applicazioni e librerie che potenziano e
aumentano le funzionalità di questo ambiente versatile e libero. Si, perché
Pure Data è un software libero, e i suoi sorgenti possono essere scaricati,

1 http://puredata.info/
2 Un algoritmo si può definire come un procedimento che consente di ottenere un risultato
atteso eseguendo, in un determinato ordine, un insieme di passi semplici corrispondenti ad
azioni scelte solitamente da un insieme finito http://it.wikipedia.org/wiki/Algoritmo

11
studiati, modificati e redistribuiti da chiunque. Inoltre Pure Data è mul-
tipiattaforma, quindi gira sui sistemi operativi più comuni: GNU/Linux,
Microsoft Windows, Apple Mac OS X, FreeBSD.

Pd è stato scritto nel 1996 da Miller Puckette, lo stesso che a metà degli
anni ’80 aveva sviluppato Max, in seguito divenuto un software commer-
ciale3 . Pd riprende le idee e i concetti di quest’ultimo, pur basandosi su
una filosofia più libera e aperta che ne fa un sistema più dinamico e dalle
prospettive future più interessanti.

1.2 P D - EXTENDED

Allo stato attuale Pd è arrivato alla versione standard 0.42.5, detta Vanilla,
scaricabile dal sito del suo creatore4 . Il consiglio di chi scrive è però quello
di scaricare la versione extended, che contiene non solo il programma stan-
dard, ma anche numerose librerie aggiuntive che estendono notevolmente
le sue funzionalità. Attualmente Pd-extended è alla versione 0.41.45 .

1.3 I NSTALLAZIONE

1.3.1 GNU/L INUX

Prendiamo in esame solo l’installazione su Ubuntu GNU/Linux, sistema


operativo sul quale è stato scritto in gran parte il presente manuale e al
quale ci riferiamo citando le combinazioni di comandi da tastiera su Pd.
Come già scritto in precedenza, il consiglio è quello di scaricare e installare
l’ultima versione di Pd-extended. Per fare questo è sufficiente aggiungere
la seguente riga al file /etc/apt/sources.list:

deb http://apt.puredata.info/releases hardy main


nel caso si stia operando in una distribuzione Ubuntu Hardy, in caso di-
verso sostituire la dicitura hardy con il mome della distribuzione di Ubuntu
installata.

3 Miller Puckett: http://crca.ucsd.edu/~msp/ Max-Msp: http://cycling74.com/


products/maxmspjitter/
4 http://crca.ucsd.edu/~msp/software.html
5 http://puredata.info/downloads

12
Successivamente si può eseguire l’installazione dal package manager di
Ubuntu, Synaptic. Aprirlo, aggiornare l’archivio dei pacchetti, cercare Pd-
extended e dopo averlo marcato far partire il processo di installazione, alla
fine del quale Pd potrà essere richiamato da un terminale digitando sem-
plicemente:

pd

Oppure dal menù Applicazioni/Audio e Video/Pd-extended

1.3.2 W INDOWS E M AC O S X

Dopo aver scaricato la versione di Pd-extended per Windows o per Mac OS


X, eseguire il file scaricato e seguire le semplici istruzioni di installazione.

13
2 PA N O R A M I C A D E L L’A M B I E N T E

2.1 P D window E patch window

All’apertura di Pd compare la finestra principale del programma (Pd win-


dow) che ha due funzioni principali:
- mostrare dei messaggi

- consentire la configurazione dell’audio e del MIDI e definire i per-


corsi in cui Pd cerca le librerie da caricare

Alcuni messaggi vengono visualizzati in fase di avvio del programma,


riguardano le librerie esterne caricate e gli eventuali errori nella configu-
razione dell’audio o del MIDI. Altri messaggi possono essere mostrati nella
Pd window durante la normale esecuzione del programmano e il più delle
volte riguardano errori di procedura o comunicazioni prodotte dall’utente
tramite l’oggetto print che sarà esaminato successivamente (vedi 2.1.2).

La configurazione dell’audio avviene tramite la voce di menù Media che


consente di impostare il MIDI (MIDI settings), l’audio (Audio settings), di
avviare il motore DSP (Audio on/off) e di testarne il funzionamento (test
Audio and MIDI).

La voce di menù File permette di aprire, chiudere, salvare le patch e di


configurare il percorso che Pd compie per trovare le librerie esterne (Path)
e quali di esse caricare all’avvio (Startup)1 .

Nella versione extended il Path e lo Startup sono già impostati per caricare
la maggior parte delle librerie necessarie per una completa funzionalità
1 Esistono numerose librerie, generalmente scritte in C o in Pd stesso, molte delle quali sono
già incluse nel pacchetto Pd-extended, altre scaricabili dal sito ufficiale o da altri siti (vedi
sitografia)

14
dell’ambiente.

Generalmente all’apertura del programma ci si trova di fronte soltanto la


Pd window. Per iniziare a scrivere gli algoritmi è necessario aprire una
finestra di patch dal menù File/new. Compare così la patch window che è
l’ambiente di programmazione vero e proprio. Il suo menù è molto sim-
ile a quello della Pd window ma ovviamente più orientato all’editing delle
patch.

La patch window può trovarsi in due stati funzionali diversi: edit mode e
run mode. Il primo permette di inserire tutti gli elementi all’interno della
finestra, mentre il secondo è necessario per gestire la patch quando questa
è in azione. Tutti gli oggetti interattivi cioè quelli che contengono parametri
modificabili via mouse o tastiera, funzionano soltanto in run mode, mentre
in edit mode possono solo essere aggiunti o rimossi. Per passare da uno
stato all’altro si usa la combinazione di tasti ctrl-E.

2.1.1 IL MOTORE DSP

Quando gli algoritmi di Pd processano esclusivamente dati, il programma


è completamente attivo sin dalla sua apertura. Nel caso in cui invece si
devono processare segnali audio, è necessario attivare il motore DSP per
ascoltare il risultato delle operazioni sui segnali. Il motore DSP, acronimo
di Digital Signal Processor, si occupa di elaborare il segnale in tempi ra-
pidissimi e di permettere la sua trasformazione da digitale ad analogico e
viceversa.
Nel momento in cui il coder vuole suonare una patch deve quindi attivare
il motore DSP, mediante l’apposita voce di menu Media/audio on. In
alternativa può premere la combinazione di tasti ctrl-/. Vedremo suc-
cessivamente le altre possibilità di intervenire sull’attivazione e la disatti-
vazione del motore DSP, quando si tratterà dell’audio nella seconda parte
del presente manuale.

2.1.2 print

Durante l’esecuzione delle patch può accadere che vengano automatica-


mente visualizzati dei messaggi nella Pd window, in particolare alla pre-
senza di errori, ma c’è un oggetto che permette al programmatore di visu-
alizzare nella Pd window il messaggio o dato che desidera. Si tratta di print,

15
che può solo ricevere dati o messaggi e stamparli a video nella Pd window.
In alcune circostanze è utile per verificare il corretto funzionamento degli
algoritmi.

Hello World!

print

Figure 1: un click del mouse sul messaggio produce un output nella Pd window

2.2 L E scatole DI P D

La finestra di patch è il luogo che permette la realizzazione degli algoritmi


di Pd. Essendo un ambiente grafico la finestra si riempirà di entità di varia
natura, dette scatole (box). Queste scatole sono di quattro tipi: oggetti, mes-
saggi, GUI e commenti e si creano dal menù Put oppure premendo ctrl+n
dove n è 1 per gli oggetti, 2 per i messaggi, 5 per i commenti. I numeri
3 e 4 creano delle GUI particolari, simboli e number box che esamineremo
successivamente.

2.2.1 OGGETTI E CONNESSIONI

Gli elementi fondamentali della programmazione in Pure Data sono gli le object box
oggetti, rappresentati dalle object box, caratterizzate dalla forma rettango-
lare e dalla presenza di entrate (inlets), nella parte superiore, e di uscite
(outlets), nella parte inferiore.

Un oggetto può creare o processare dati oppure segnale audio e riceve


attraverso gli inlets messaggi, liste o uscite di altri oggetti. Può inviare dati
o segnali ad altri oggetti. All’interno dell’object box si situano gli atomi, cioè
stringhe di caratteri o simboli separati da spazi che rappresentano il tipo
di oggetto e gli eventuali argomenti dell’oggetto stesso2 .
2 il concetto di atomo è mutuato dal Lisp, un linguaggio di programmazione orientato
all’elaborazione di espressioni simboliche rappresentate sotto forma di liste e atomi. Una lista
si ha in presenza di più espressioni Lisp, un atomo invece è una lista con una sola espres-
sione. Per approfondire: www.diee.unica.it/~roli/IA/Materiale%20didattico/AA0910/
Lisp.pdf

16
random 250

Figure 2: un esempio di object box: l’oggetto metro con un argomento

I collegamenti fra oggetti, anzi fra tutte le object box avvengono tramite
cavi di connessione che si realizzano tenendo premuto il tasto sinistro del
mouse a partire dall’outlet mittente e rilasciandolo non appena si è rag-
giunto l’inlet di arrivo.

random

select 0 5 7

Figure 3: collegamenti fra object box

L’inlet di sinistra di ogni oggetto è detto caldo poiché alla ricezione di un


messaggio, di un dato o di un segnale, produce immediatamente un’uscita
dall’oggetto stesso. Tutti gli altri inlets sono freddi, quindi nel momento
in cui ricevono un dato, messaggio o segnale, lo inseriscono temporanea-
mente all’interno dell’oggetto, fino a che lo stesso non viene processato
all’attivazione dell’inlet caldo.

counter

pack 0 0

Figure 4: l’entrata fredda riceve un dato dall’oggetto counter, ma pack non produce
alcun dato in uscita finché l’inlet caldo non riceverà qualcosa

17
Come già detto, gli oggetti insistono su dati o segnali audio. Graficamente
gli oggetti-audio si distinguono da quelli per i dati perché il primo atomo
(ovvero il nome) termina sempre con il segno della tilde (∼) e gli inlet e
outlet che processano segnale sono scuri. I cavi che trasportano segnale
sono più spessi di quelli che trasportano dati.

random 1000

osc~

dac~

Figure 5: confronto visivo fra oggetti-dato e oggetti-audio

2.2.2 MESSAGGI E LISTE

Le message box hanno forma rettangolare con il lato destro rientrante. Pos-
sono contenere stringhe di caratteri, numeri, liste o variabili e vengono at-
tivati con un click del mouse quando si è in run mode oppure alla ricezione
di un altro messaggio o di particolari azioni.

questo è un messaggio

print

Figure 6: un click con il mouse sul messaggio produce un output del messaggio
stesso nella Pd window

18
bang E number box

Un altro modo di attivare un messaggio è quello di utilizzare un bang, uno


dei più importanti oggetti di Pd. La sua funzione è quella di innescare
un’azione o una sequenza di azioni, può mettere in funzione un algoritmo.
Si avrà modo di incontrarne praticamente in ogni patch.

questo è un messaggio

print

Figure 7: la stessa patch precedente, con la differenza che il messaggio viene atti-
vato da un click del mouse sul bang

Il bang ha una sua versione grafica (si ottiene premendo all’interno della
patch ctrl+shift+b e una doppia versione testuale, che permette di evitare
un eccessivo uso di elementi grafici che appesantiscono l’esecuzione dei
programmi.

bang grafico

bang

oggetti bang
b

Figure 8: le varie versioni del bang

Un altro oggetto molto comune nelle patch di Pd è la number box che


consente di inviare messaggi numerici con il vantaggio di poter variare
i numeri all’interno della box stessa con la pressione e il trascinamento
del mouse verso il basso per diminuire e verso l’alto per aumentare il nu-
mero stesso. Per comodità è possibile stabilire eventuali minimi e massimi
della number box premendo il destro del mouse e andando sulle proprietà

19
dell’oggetto3 . Una number box può inviare o ricevere dati attraverso i suoi
inlet.

+ 5

12

Figure 9: l’oggetto ’+’ effettua in questo caso la somma fra il numero che entra
nell’inlet di sinistra e 5, e manda l’output alla number box sottostante

3 La finestra delle proprietà è attiva in Pd per tutti i tipi di GUI e consente di configurare
una serie di parametri come la veste grafica o i valori consentiti

20
3 BASI DI PROGRAMMAZIONE CON
P U R E DATA

3.1 VARIABILI E COSTANTI

Pure Data è un linguaggio di programmazione orientato all’audio, quindi


al tempo. Per tale ragione i valori e le quantità passate agli oggetti sono
quasi sempre variabili, interattivamente o meno. In fase di apertura di una
patch ci potranno essere delle quantità inizializzate, ma esse all’occorrenza
potranno essere variate durante l’esecuzione del programma. Ne sono es-
empio i parametri passati agli oggetti dall’interno dell’objet box, cioè gli
atomi che seguono il primo (il quale, ricordiamo, da il nome all’oggetto
stesso).

Per comprendere meglio questo concetto esaminiamo la patch che abbiamo


già incontrato nella figura 9 . L’inlet di sinistra dell’oggetto ’+’ riceve una
quantità variabile che viene sommata alla costante ’5’ definita all’interno
dell’object box. Così com’è la patch non fa altro che operare una somma
fra la quantità in entrata e la costante definita nell’oggetto. L’inlet destro
dell’oggetto ’+’ offre però l’opportunità di variare il secondo addendo
della somma.

10 20

+ 5

30

Figure 10: è possibile cambiare a piacimento gli addendi della somma

21
Esaminiamo il comportamento della patch in figura 10: se cambiamo il
primo elemento dell’addizione senza toccare il secondo, l’output sarà lo
stesso di prima: somma del primo elemento con 5. Ora proviamo a cam-
biare il secondo addendo. Non avremo alcun output!

Non va dimenticato che gli inlet successivi al primo di sinistra sono freddi:
immagazzìnano il dato in entrata senza produrre uscita. E’ necessario
quindi dire all’oggetto ’+’ di effettuare l’operazione fra i due nuovi ad-
dendi e di far uscire il risultato. Nel caso di questo oggetto è sufficiente
inserire nell’inlet di sinistra un bang, collegato all’uscita del secondo ad-
dendo, che ordina all’object box di far uscire il risultato immediatamente1 .

14 3

+ 5

17

Figure 11: il bang collegato all’uscita del secondo addendo, in entrata nell’inlet
sinistro dell’oggetto ’+’ rende caldo l’inlet destro dell’oggetto stesso

E’ buona norma stabilire dei valori in fase di inizializzazione della patch in


modo che essa sia immediatamente funzionante alla sua apertura. Per fare
questo è sufficiente scrivere i parametri degli oggetti all’interno delle object
box. Quando questo non è possibile si può ricorrere al’oggetto loadbang che
attiva un bang all’apertura della patch (figura 12).
Vi sono circostanze in cui è necessario specificare delle variabili all’interno
delle object box. Questo è possibile attraverso il simbolo $n, dove n è un

1 L’oggetto ’+’ oltre ad accettare numeri in entrata, accetta anche bang nell’inlet di sinistra. Il
bang non fa altro che dire all’oggetto di far uscire ciò che ha in memoria, cioè il risultato
dell’addizione

22
loadbang

+ 5

12

Figure 12: all’apertura della patch si avrà come output la somma fra 7 e 12

numero identificativo. La variabile assume di volta in volta il valore che la


message box riceve nel suo inlet (figura 13)2 .

12

scelgo il numero $1

print

Figure 13: variabile in una message box, osservare l’output nella Pd window

3.1.1 pack E unpack

Nel caso in cui una messege box contenga più di una variabile è necessario
che ognuna abbia un’univoca denominazione. Così la prima variabile sarà
$1, la seconda $2 e così via.

L’inlet del messaggio riceve una lista con i valori che le variabili devono
assumere. Per realizzare tali liste esiste un oggetto apposito chiamato pack,

2 I simboli identificativi delle variabili devono iniziare da $1 e seguire ordinatamente. Se una


message box ha 3 variabili $1 $2 ed $3 e riceve una lista di 3 atomi, il primo andrà nella
variabile $1, il secondo nella $2, etc. . .

23
che mette insieme diversi valori singoli (atomi), combinandoli in liste. Gli
argomenti di pack inizializzano il valore del relativo inlet al valore segnato.
Ad esempio pack 2 19 25 avrà 3 inlet rispettivamente inizializzati con i valori
2, 19, 25. Un bang in entrata nell’inlet sinistro produrrà l’output della lista
in memoria in quel momento (fig. 14).

0 0 0

pack 20 1 2010

la data di oggi: giorno $1 mese $2 anno $3

print

Figure 14: pack: un click sul bang senza cambiare i valori delle number box produce
l’uscita dei valori inizializzati. Una variazione delle number box pro-
duce un output nel momento in cui viene cambiato il valore dell’inlet
di sinistra. Osservare il risultato nella Pd window

L’oggetto unpack fa il contrario rispetto a pack: prende una lista e ne con-


voglia i singoli atomi attraverso i suoi inlet.

3.2 G ESTIONE DEL TEMPO

Come detto in precedenza, Pd è un linguaggio orientato al tempo, quindi


ci sono molti oggetti deputati alla gestione di eventi temporali. Esaminer-
emo alcuni di questi senza dimenticare che la presente trattazione non può
trattare di molti altri oggetti che il programmatore scoprirà nel suo cam-
mino3 .
3 Premendo il destro del mouse su un oggetto si può accedere all’help dello stesso. In molti
casi la pagina dell’help rimanda anche ad oggetti simili a quello esaminato. E’ sempre
utilissimo pertanto navigare fra le pagine di help che sono uno strumento di navigazione
fondamentale fra gli oggetti di Pd.

24
20 1 2010

unpack 0 0 0

20 1 2010

Figure 15: unpack: un click sulla message box produce un output in ognuno dei tre
outlet

3.2.1 metro

L’oggetto metro produce in output un bang ogni n millisecondi, dove n è


l’argomento dell’oggetto e rappresenta la distanza temporale fra un bang e
l’altro. Per funzionare ha bisogno che sia attivato attraverso un messaggio
diverso da zero o un bang. Un messaggio uguale a zero oppure stop, spegne
l’oggetto.

1 un numero diverso da 0 o un
"bang" attivano metro
bang

0
0 o "stop" fermano metro
stop

l'inlet di sinistra consente


0
di modificare la distanza
metro 500 temporale fra i "bang"

Figure 16: metro

25
UN CONTATORE

Attraverso l’oggetto metro e un altro oggetto che esamineremo in questo


paragrafo, possiamo costruire un contatore4 . La patch non fa altro che
emettere a intervalli regolari (nel nostro caso 500 ms) un numero intero a
partire da zero tale che il successivo sia maggiore del precedente di una
unità. L’algoritmo necessita di un oggetto che permetta di conservare in
memoria un numero intero. L’oggetto che fa al caso nostro è int. L’inlet de-
stro di int riceve un intero e lo memorizza finché un bang nell’inlet sinistro
non lo costringe a inviarlo dall’outlet. All’apertura della patch l’oggetto
int viene inizializzato con uno zero nella sua memoria (tramite loadbang.
All’attivazione di metro, int riceve un bang nella sua entrata calda facendo
uscire zero, che viene mandato all’uscita della patch e contemporaneamente
viene sommato a 1, tramite l’oggetto ’+’. Quest’ultimo a sua volta spedisce
il risultato, cioè uno, nell’entrata fredda di int. Il nuovo valore (uno) uscirà
non appena il successivo bang prodotto da metro non sopravvenga, e così
via (figura 17).

3.2.2 line

Un oggetto molto comune in Pd è line, che generara delle rampe per rag-
giungere un determinato valore. line ha bisogno di almeno due argomenti,
il valore-obiettivo, cioè la quantità da raggiungere, e il tempo in millisec-
ondi necessario a raggiungerlo. In presenza di un messaggio con una lista
di due numeri, line raggiungerà il primo nel tempo in millisecondi indicato
dal secondo (figura 18).
Un oggetto molto comune in Pd è line, che generara delle rampe per rag-
giungere un determinato valore. Accetta due argomenti via message box,
ovvero il valore-obiettivo e il tempo in millisecondi per raggiungerlo (fig.
18).
Una volta terminato il suo percorso line mantiene in memoria il valore-
obiettivo, quindi un secondo click sulla message box non produrrà un nuovo
output perché si direbbe a line di creare un percorso da 1000 a 1000 in
5 secondi. Se volessimo reinizializzare ogni volta l’oggetto line ad esem-
pio chiedendogli di creare ogni volta il percorso da 0 a 1000 in 5 secondi,
basterà creare una lista di tre atomi, con il primo che indica il valore di

4 In generale un contatore è un dispositivo che memorizza (e a volte visualizza) il numero


di volte che un particolare evento o processo si verifica. In una caso molto semplice, un
contatore può contare i bang che riceve ed emettere il conteggio dal suo outlet.

26
0 1

metro 500

loadbang

int

+ 1

23

Figure 17: click su 1 per avviare il contatore, su 0 per fermarlo

partenza, il secondo con il valore-obiettivo, separato dal precedente da


una virgola e infine con il tempo in millisecondi (figura 19).
line puÚ avere anche due argomenti interni alla object box:

1. Il valore da cui iniziare la prima rampa (default 0)

2. La distanza di tempo in millisecondi fra l’uscita di un valore e il


successivo (default 20 ms)

Nella figura 20 il valore-obiettivo è 2000, da raggiungere in 5 secondi. La


rampa inizia da 1000 e i valori escono ogni mezzo secondo (500 ms).

3.2.3 delay

L’oggetto delay emette un bang dopo aver ricevuto un bang a sua volta.
L’unico argomento che accetta (dall’inlet destro) è il ritardo con cui verrà
emesso il bang stesso (figura 21).

27
1000 5000

line

Figure 18: line al momento della creazione è inizializzato a zero, quindi in questo
caso al momento del click sulla message box inizierà un percorso da 0 a
1000, completandolo in 5 secondi

0, 1000 5000

line

Figure 19: si può ricominciare la rampa da 0 a 1000 ogni volta che si preme sulla
message box

2000 5000

line 1000 500

Figure 20: rampa da 1000 a 2000 in 5 secondi, con step di mezzo secondo fra un
valore e l’altro in uscita

28
1

metro 1000

delay 500

Figure 21: i bang saranno intermittenti

3.2.4 line MULTIRAMPA CON delay

Con gli oggetti line e delay possiamo costruire rampe multiple in modo
molto semplice. E’ sufficiente preparare tante message box quante saranno
le rampe e metterle in azione in successione con delay. Nel caso della patch
in figura 22 c’è un oggetto grafico per rappresentare le rampe, una slider
orizzontale, di cui ci occuperemo in un apposito capitolo.

3.3 A RITMETICA

Pd dispone di una serie di oggetti che consentono di effettuare le più co-


muni operazioni matematiche. Abbiamo già incontrato l’oggetto ’+’ che
permette l’operazione di somma. Nel prossimo paragrafo esamineremo
alcuni altri oggetti per operare sui numeri.

3.3.1 OPERATORI ARITMETICI

Gli oggetti per le operazioni aritmetiche e matematiche funzionano tutti


allo stesso modo, per ora ci limitiamo a darne qui un elenco. Successiva-
mente avremo modo di usarli massicciamente.

Operazioni aritmetiche:

• +

• -

29
delay 1000 delay 1600

0, 127 1000 50 600 100 1500

line

Figure 22: click sul bang pi˘ in alto della patch

• *

• /

• pow

Operazioni trigonometriche:

• sin

• cos

• tan

• atan

• atan2

Operazioni sulle frazioni

• mod

• div

e molti altri...

30
3.3.2 expr

expr è un versatile strumento che permette di raggruppare in un unico


oggetto una serie di operazioni. Con Pd può capitare spesso di dover
effettuare una sequenza di operazioni matematiche, attraverso expr si pos-
sono combinare insieme in modo da non occupare spazio e da rendere più
chiara per il programmatore la sequenza delle operazioni stesse. Per poter
funzionare con dei dati in ingresso expr necessita di simboli per rappre-
sentare delle variabili, che, a differenza delle variabili delle message box si
scrivono in questa forma: $xn dove x è il tipo della variabile e n è il numero
ordinale che la rappresenta (fig. 23).
Le variabili possono essere di tipo intero, decimale, simbolo e rispettivamente
avranno la forma $in, $fn e $sn.

+ 12 expr (($f1 + 12) * 24)/(($f1 + 12) - 7)

* 24 - 7

42.6667 42.6667

Figure 23: nella parte sinistra le operazioni si succedono dall’alto verso il basso,
nella parte destra le stesse vengono raggruppate da expr. Valutare i
due algoritmi in parallelo con un click sul bang

31
3.4 G ENERATORI DI NUMERI CASUALI

Dopo i più comuni operatori matematici é utile soffermarsi su alcuni oggetti


di Pd che generano numeri casuali. Qualunque coder prima o poi si imbatte
nell’esigenza di usare numeri casuali e chi usa Pd non fa eccezione. Il
primo strumento che esaminiamo é random che genera un numero casuale
ogni volta che riceve un bang. Questo numero viene scelto in un range com-
preso fra 0 e il numero definito nel primo argomento dell’oggetto meno 1.
Un secondo argomento, facoltativo, imposta il seme della sequenza. Senza
volersi soffermare troppo sulle implicazioni tecniche della generazione di
numeri casuali, c’é da dire quantomeno che generalmente quando si parla
di generatori di numeri casuali si usa un termine improprio, perché in
realtà si tratta di generazione di numeri pseudo-casuali, poiché questi ven-
gono generati da algoritmi. Nel caso di Pd alla base della generazione
di questi numeri c’é una complessa equazione con una serie di variabili.
Il seme della sequenza generata non é altro che una variabile di questa
equazione.

1 0

metro 500

random 250

Figure 24: la patch genera un numero pseudo-casuale ogni mezzo secondo

random produce solo interi, ma se volessimo generare dei numeri pseudo-


casuali decimali potremmo semplicemente dividere l’output (figura 25).
L’oggetto randomF fa la stessa cosa, ma con una precisione molto maggiore.
Se invece volessimo creare una sequenza di numeri pesata, cioé generata
con una certa probabilità potremmo usare l’oggetto moses che consente di
convogliare un flusso di numeri in due outlet diversi in base a un valore-
soglia definito come argomento. I numeri al di sotto del valore-soglia ven-
gono convogliati dall’outlet sinistro, quelli al di sopra da quello destro.

32
1 0

metro 500

random 1001

/ 1000

Figure 25: la patch genera un numero pseudo-casuale compreso fra 0 e 1, con 3


cifre decimali

1 0

metro 500

random 100

moses 25

Figure 26: i numeri da 0 a 24 producono un bang dall’outlet sinistro, quelli da 25 a


99 dal destro. Volendo parlare di percentuali, l’outlet sinistro ha il 25%
di possibilità di produrre un bang, quello destro il 75%

L’oggetto decide produce pseudo-casualmente solo sequenze di 0 e 1, men-


tre drunk funziona come random ma sceglie il numero effettuando un salto
che lo distanzia dal precedente al massimo quanto stabilito nel secondo
argomento (stepsize).
In figura 28 si può osservare il diverso andamento di due sequenze casuali.
La prima, generata con random, ha una distribuzione lineare, la seconda,

33
1 0

metro 500

drunk 100 10

80

Figure 27: ogni mezzo secondo viene generato un numero compreso fra 0 e 99,
dove ogni numero é a una distanza minore o uguale 10 dal precedente

frutto di drunk é molto più ordinata: gli elementi della sequenza si spostano
entro un range limitato (definito dal secondo argomento di drunk).

3.5 C ONNESSIONI SENZA CAVI

Al fine di evitare di riempire la patch window di cavi che possono renderne


meno chiara l’interpretazione, si possono usare i due oggetti send e receive,
che permettono di creare una connessione senza fili fra le box. L’argomento
di receive è un nome identificativo che deve essere identico a quello di send.
E’ possibile avere più oggetti receive con lo stesso identificativo: tutti ricev-
eranno dall’oggetto send che ha lo stesso nome. Un’ultima annotazione,
send e receive possono essere abbreviati in ’s’ e ’r’ (fig. 29).

3.6 Subpatches E Abstractions

Ci sono circostanze in cui le patch sono molto complesse e articolate. In


questi casi Pd mette a disposizione degli strumenti per annidare delle porzioni
di patch in box apposite. Esistono due modi per annidare contenuti dentro
tali box, il primo è quello di creare delle subpatch, l’altro quello di creare
abstraction. Le subpatch appaiono come delle normali object box formate
dal nome pd seguito da un nome identificativo per la subpatch, esse pos-
sono essere utilizzate solo all’interno della patch dove sono state create o
all’interno di altre subpatch della stessa patch. Le abstraction invece, pur ap-
parendo come delle normali object box, hanno solo un nome identificativo,

34
random

drunk

Figure 28: in alto la sequenza generata da random, in basso quella creata con drunk,
con una stepsize di 25

ma vengono salvate indipendentemente dalla patch in cui vengono usate e


sono riutilizzabili in altre patch.

3.6.1 subpatch

Per creare una subpatch é sufficiente scrivere all’interno di una nuova object
box pd nome, si aprirà una nuova finestra all’interno della quale si inserirà
il contenuto della subpatch. Questa nuova finestra si può chiudere in qual-
sisasi momento senza bisogno di salvarla e riaprirla con un semplice click
sulla object box in run mode. La patch in figura 30 realizza un algoritmo at-
traverso il quale vengono emessi dei bang da quattro outlet diversi, il primo

35
4 r numero

send numero
4

r numero
receive numero
* 2
4
8

Figure 29: connessioni senza fili

metro 500

random 500

+ 1

moses 250

moses 126 moses 376

Figure 30: un semplice algoritmo senza annidamenti

da sinistra se random emette un numero fra 1 e 125, il secondo se il numero


é compreso fra 126 e 250, e cosÏ via. L’algoritmo della figura 31 é identico
al precedente, con l’unica differenza che é realizzato con una subpatch. Le

36
subpatch funzionano esattamente come le patch solo che devono contenere
al loro interno le entrate e le uscite necessarie perché siano, nella patch,
collegabili alle box da cui ricevono dati e a cui li inviano.

pd miasubpatch

Figure 31: l’algoritmo precedente realizzato con una subpatch

Come si può vedere dalla figura 32 l’interno della subpatch del nostro
algoritmo é uguale alla porzione di patch della figura 30, ma in alto c’é
l’oggetto inlet che crea un inlet nella subpatch e 4 oggetti outlet, che creano
i rispettivi 4 outlet per i bang. Le subpatch possono essere modificate in

inlet

metro 500

random 500

+ 1

moses 250

moses 126 moses 376

outlet outlet outlet outlet

Figure 32: l’interno della subpatch con gli inlet e gli outlet

qualunque momento e, soprattutto, possono essere duplicate a piacimento.


Rappresentano uno strumento molto comodo per rendere più leggibile e

37
chiaro un algoritmo nella patch window, quindi il consiglio é di usarle il più
possibile.

3.6.2 abstraction

Un’abstraction non è altro che una patch che può essere richiamata dall’interno
di una patch. Anch’essa, come la subpatch contiene gli oggetti inlet e outlet
per creare le varie entrate e uscite dell’object box e, a differenza della sub-
patch, può essere utilizzata in qualunque patch. L’importante è che il file
dell’abstraction sia salvato con l’estensione .pd e che si trovi nella stessa
directory in cui si sta lavorando o in una delle directory definite nel Path del
programma (cap. 2.1).

Per richiamare un’abstraction è sufficiente aprire un’object box e inserire


il nome dell’abstraction senza l’estensione .pd. L’abstraction potrà essere
aperta e chiusa in qualunque momento e anche modificata, a patto che
sia salvata, ma il consiglio è di stare attenti a modificare un’abstraction
dall’interno di una patch: l’abstraction risulterà modificata in tutti gli altri
progetti in cui viene utilizzata!

Un’abstraction può anche essere inizializzata con un argomento, questo è


possibile scrivendo l’argomento stesso (o gli argomenti) dopo il nome. Il
primo argomento determina il valore della variabile $1, il secondo quello
della variabile $2 e così via. Queste variabili possono essere create all’interno
degli oggetti dell’abstraction, ma non dentro le message box.

myabstraction 100 1000

Figure 33: un’abstraction con due argomenti

Osserviamo la figura 33: l’oggetto myabstraction viene inizializzato con due


argomenti: 100 per la variabile $1, 1000 per la variabile $2. Un bang mette
in azione l’abstraction. Ma vediamo cosa accade al suo interno (figura 34).
I due argomenti inviati tramite l’object box myabstraction si sostituiscono

38
inlet

pack $1 $2

line

outlet

Figure 34: l’interno dell’abstraction

a $1 ed $2, che sono le variabili di pack, che riceve quindi la lista (100
1000) che sono rispettivamente il valore-obiettivo e il tempo in millisecondi
dell’oggetto line. Un bang ricevuto dall’inlet dell’abstraction mette in azione
line restituendo la rampa all’outlet.

3.6.3 GRAPH ON PARENT

subpatch e abstraction possono anche essere pilotate dalla patch senza bisogno
di essere aperte ogni volta ci fosse il bisogno di cambiare un valore. In
sostanza subpatch e abstraction possono diventare oggetti interattivi. Per
fare questo una delle soluzioni potrebbe essere quella di creare degli inlet
aggiuntivi nella subpatch oppure utilizzare un’altro metodo che Pd mette a
disposizione. Se nelle proprietà della subpatch (o dell’abstraction, questo sis-
tema funziona su entrambe), cui si accede premendo il sinistro del mouse
su un punto qualunque della subpatch window, selezioniamo l’opzione graph
on parent, comparirà all’interno della subpatch stessa un riquadro all’interno
del quale possiamo mettere ciò che vogliamo sia visibile dalla patch geni-
trice. Gli oggetti consentiti sono essenzialmente GUI’s, quindi number box,
sliders, radio button etc. . .
Nel caso della figura 35 la subpatch submetro contiene un oggetto metro con
una number box che regola la distanza in millisecondi fra i bang.
I cavi di connessione vengono nascosti nella patch in modo da rendere più
chiara la lettura dell’algoritmo.

39
1 0

pd submetro

regola_metro
301

Figure 35: Una subpatch con una number box in graph on parent

inlet

regola_metro
301

metro 500

outlet

Figure 36: l’interno della subpatch. Per creare il riquadro di visibilità basta andare
sulle proprietà della subpatch e selezionare l’opzione graph on parent

40
4 V E T TO R I , G R A F I C I E TA B E L L E

4.1 V ETTORI

Un vettore (in inglese array) è un oggetto che permette di conservare e ma-


nipolare comodamente una grande quantità di dati. Può essere pensato
come un contenitore di locazioni di memoria, identificate da un indice, at-
traverso il quale è possibile accedere alla locazione desiderata. I vettori
in Pd sono rappresentati da grafici bidimensionali che hanno sull’ascissa
l’indice e sull’ordinata il valore corrispondente. Si tratta sempre di vettori
monodimensionali che gestiscono collezioni di numeri interi, decimali o di
segnale (ma di questi ultimi ci occuperemo in seguito) quindi l’indice è un
intero che identifica una e una sola posizione in memoria. Nel linguaggio
C i vettori monodimensionali vengono definiti, come le variabili, in questo
modo:

int i[4] = {5, 2, 7, 3}

che crea il vettore i di tipo intero di 4 elementi. Immediatamente dopo


riempie il vettore con i valori interi 5, 2, 7, 3. In Pd questo vettore viene
rappresentato come in figura 37.
Ricordiamo che l’indice di un vettore inizia da 0, quindi un vettore di
4 elementi avrà un indice che va da 0 a 3. Un array in Pd si crea dal
menu Put/Array. Se premiamo col destro del mouse sul grafico possiamo
accedere alle proprietà dell’array, dove possiamo impostare la dimensione
del grafico e del vettore. Osserviamo dalla figura 37 le seguenti cose:
1. all’interno del grafico ci sono delle barrette orizzontali che rappresen-
tano le coordinate (x, y) degli elementi

2. in alto a sinistra del grafico c’è il nome del vettore (in questo caso i)

3. incolonnati a sinistra ci sono dei valori che rappresentano il range


dell’ordinata, quindi dei valori che può assumere ogni elemento dell’array

41
i
10

0
0 1 2 3

Figure 37: vettori: sull’asse delle ascisse c’è l’indice, sull’ordinata il valore

4. in riga in basso ci sono invece i valori dell’indice

Punto 1. Il grafico di un vettore può essere riempito in numerosi modi:

- interattivamente, cioè con il mouse

- con una message box che invia i dati al grafico stesso. La sintassi di
una message box per un vettore è la seguente:
;
nome_vettore (comando) argomenti

Si possono scrivere esplicitamente i singoli valori inserendo nella mes-


sage box l’indice del primo elemento da scrivere seguito da tutti i val-
ori da inserire nel vettore. Si possono possono produrre i valori del
vettore attraverso una funzione trigonometrica come sinesum (somma
di seni), seguita dal numero degli elementi del vettore e dal valore di
ogni curva sinusoidale (compreso fra 0 e 1), oppure cosinesum, uguale
alla precedente, ma che genera una cosinusoide o una somma di cos-
inusoidi. Si possono inoltre leggere i dati richiamandoli da un file di
testo con il comando read seguito dal nome del file che contiene di
dati (figura 38).

42
- con oggetti speciali che scrivono i dati all’interno dei vettori. L’oggetto
tabwrite scrive valori all’interno di un vettore. Nell’inlet di sinistra en-
trano i valori, in quello di destra i relativi indici. Il messaggio set
in entrata a sinistra determina il nome dell’array sul quale operare,
nome che può anche essere inserito nell’oggetto come argomento,
subito dopo il nome (figura 39).

;
i resize 4
i 0 0.5 0.75 -0.6 0.1

;
i sinesum 32 0.5

;
i cosinesum 32 0.25 0.5 0.25

Figure 38: attivare le tre message box con un click e verificarne il risultato sul
grafico. Il comando resize ridimensiona il vettore secondo quanto indi-
cato dal suo argomento, in questo caso 32

Nella patch della figura 39 until provoca l’uscita di una sequenza di 32


bang che vengono numerati da un contatore, che a sua volta li spedisce
all’inlet destro di tabwrite (l’indice dell’array). Contemporaneamente i bang
producono l’uscita di numeri pseudo-casuali decimali, compresi fra 0 e 2,
dall’oggetto randomF. Da questi ultimi viene sottratto 1 in modo da avere

43
i
1

-1
32

until

int 1 + 1
randomF 2

- 1

tabwrite i

Figure 39: click sulla message box in alto e verificare il risultato sul grafico

un range compreso fra -1 e 1, che rappresentano i valori minimi e massimi


del grafico del vettore.

Punti 2-4. L’interfaccia del vettore, il grafico, può presentare anche ele-
menti come un etichetta che rappresenta l’ordinata e uno che rappresenta
l’ascissa. Questi elementi si possono aggiungere tramite message box sec-
ondo le seguenti sintassi:

44
nome_vettore xlabel posizione valori_ascissa_da_mostrare
nome_vettore ylabel posizione valori_ordinata_da_mostrare
nome_vettore xticks posizione intervallo intervallo_tick_grande
nome_vettore yticks posizione intervallo intervallo_tick_grande

Gli stessi comandi seguiti da hide rimuovono i risultati del comando. Per
verificare il funzionamento di questi comandi si copi il codice della figura
40, che mostra un vettore di 100 punti, con range da -1 a 1.

i
1

-1
0 100

; ;
i xlabel -1.2 0 100 i xlabel hide

; ;
i ylabel -5.5 -1 0 1 i ylabel hide

; ;
i xticks 0 2 10 i xticks hide

; ;
i yticks 0 0.1 5 i yticks hide

Figure 40: click sulle message box per aggiungere o rimuovere le etichette

45
Fra le proprietà del grafico si può anche impostare il modo con cui verrà
disegnato il grafico: come punti discreti (draw as points), come punti inter-
polati (polygon) cioè singoli punti uniti da una linea che traccia il percorso
pi˘ breve fra punti adiacenti, infine come curva di bézier (bézier) che smussa
gli spigoli (figura 41).
i punti i polygon

i bezier

Figure 41: le tre diverse rappresentazioni di un vettore di 16 punti

4.1.1 LEGGERE UN VETTORE

Un vettore può essere letto e utilizzato per processare altri dati. Uno degli
oggetti che permettere di leggere i dati di un vettore è tabread che ha un
unico inlet che riceve l’indice del valore da restituire. Nella figura 42 tabread
legge tutti i valori del vettore i e a sua volta li riscrive in un nuovo vettore
(new) che disegna i valori sul grafico uno ad uno. Allo stesso tempo tabread
modifica la dimensione di un bang e il movimento dell’indicatore di una
slider verticale.

4.1.2 L’ OGGETTO table

L’oggetto table è simile ad un normale oggetto array con l’unica differenza


che crea il grafico in una subpatch invece che nella patch window dove
viene creato l’oggetto. Il primo argomento è il nome dell’array, il secondo,
opzionale è la sua dimensione. E’ inoltre possibile mandare messaggi al
vettore, con i consueti metodi visti nei paragrafi precedenti.

46
i reset

16

s reset until

0
0
int + 1

1 0 tabwrite new

new
metro 1000

r reset

int 0 + 1

mod 16

t i i sel 15

tabread i $1 950

0, $1 950 line

line size $1

tabwrite new

Figure 42: click sulle message box per aggiungere o rimuovere le etichette

47
5 P R O G R A M M A Z I O N E AVA N Z ATA

5.1 I STRUZIONI CONDIZIONALI

Nella logica della programmazione le istruzioni condizionali sono gli stru-


menti che permettono di verificare se una data condizione sia vera o falsa1 .
In Pd, come nella maggior parte degli altri linguaggi di programmazione,
esistono degli oggetti e dei costrutti sintattici che permettono di verificare
una condizione e di eseguire delle operazioni al verificarsi di determinate
situazioni. Tutti queste istruzioni possono essere raccolte e combinate in
algoritmi di selezione.

5.1.1 OPERATORI RELAZIONALI

Gli operatori relazionali consentono di confrontare due valori fra loro, quindi
sono binari. Come nel linguaggio C producono un output uguale a 1 se la
condizione richiesta dall’operatore relazionale è soddisfatta, uguale a 0 in
caso contrario. I principali operatori relazionali sono sei:

• > (maggiore di)

• < (minore di)

• >= (maggiore o uguale a)

• <= (minore o uguale a)

• == (uguale a)

• != (diverso da)

1 Il concetto di vero o falso è mutuato dalla logica classica che ha prestato al mondo
dell’informatica i suoi modelli. La primitiva fondamentale dell’informatica, il bit, può infatti
assumere il valore di 1 o 0, acceso o spento, vero o falso.

48
0

> 10

Figure 43: L’output di ’>’ restituisce 0 finché il numero in entrata é minore o


uguale a 10, 1 quando diventa maggiore di 10

5.1.2 select

select (forma abbreviata: sel) opera una selezione sugli atomi in entrata
confrontandoli con i suoi argomenti. Se la condizione è soddisfatta select
emette un bang dall’outlet corrispondente, in caso contrario spedisce fuori
l’atomo in entrata dall’ultimo outlet a destra.

5 123 10

sel 10

Figure 44: select

select può selezionare più atomi, in tal caso avrà tanti outlet quanti saranno
gli atomi da valutare, più uno, da cui farà uscire gli atomi che non soddis-
fano la selezione (figura 45).
Con gli operatori relazionali e select realizziamo un algoritmo che opera
una selezione su dei numeri. Quando la selezione è soddisfatta e select
emette 1, verrà attivata una rampa con l’oggetto line (figura 46).

49
5

123

10

sel 10 4

Figure 45: select con più selezioni

20 32 69

> 50

sel 1

0, 127 2000

line

Figure 46: valutare l’algoritmo con un click sulle 3 message box in alto

Se volessimo modificare questo algoritmo in modo da operare una verifica


su una rampa invece che su valori singoli, avremmo bisogno di uno stru-
mento che individui il superamento di una soglia. L’oggetto che fa al caso
in questione è change, che filtra le ridondanze in un flusso in entrata. Ad
esempio se in change entra per 10 volte consecutive il numero 1, emetterà 1

50
solo alla prima entrata. Combinando così ’>’ e change possiamo soddisfare
la nostra richiesta.

0, 100 2000

line

100

> 50

change

sel 1

0, 127 2000

line

Figure 47: click sulla message box in alto

Esaminiamo la patch in figura 47: all’attivazione della rampa, inizia il cam-


mino da 0 a 100 effettuato da line. Appena superato il valore-soglia di 50,
l’operatore ’>’ emette 1 a ripetizione, ma change elimina tutte le ripetizioni
successive, consentendo l’uscita solo del primo 1, attivando così il selettore
sel un’unica volta. Si attiva in quel momento la rampa in basso.

5.1.3 OPERATORI LOGICI

Gli operatori logici eseguono operazioni secondo le tavole di verità dell’algebra


booleana2 . In Pd ci sono operatori che operano al livello di bit e altri che op-
erano sui numeri decimali. Nel primo caso i numeri interi decimali ricevuti
dagli operatori logici vengono trasformati nella loro forma binaria e ogni
2 Le tavole di verità sono tabelle usate nella logica per determinare se, attribuiti i valori di
verità alle proposizioni che la compongono, una determinata proposizione è vera o falsa.

51
bit viene valutato con il bit dell’altro numero che si trova nella stessa po-
sizione. Ad esempio l’operatore AND (oggetto ’& ’ in Pd) segue le regole
della tavola di verità illustrate nella tabella 1.

a b a∧b
0 0 0
0 1 0
1 0 0
1 1 1

Table 1: tavola di verità per l’operatore AND

Se volessimo realizzare un AND sugli interi 21 e 6, ’& ’ opererebbe nel


modo illustrato nella tabella 2.

21 = 1 0 1 0 1 ∧
6 = 0 0 1 1 0 =
4 = 0 0 1 0 0

Table 2: operazione AND su gli interi 21 e 6

t b b

21 6

&

Figure 48: l’operatore AND in azione in una patch di Pd

52
L’operatore OR (in Pd ’|’) agisce allo stesso modo ma seguendo le regole
della tavola di verità dell’OR booleano (tabella 3).

a b a∨b
0 0 0
0 1 1
1 0 1
1 1 1

Table 3: tavola di verità per l’operatore OR

t b b

41 22

63

Figure 49: l’operatore OR

In relazione a questi due operatori ci sono due oggetti (’&& ’ e ’||’) che
confrontano due valori (interi o decimali) producendo come risultato lo
stesso delle tavole di verità su citato. Ad esempio ’&& ’ restituisce 1 se e
solo se entrambi i valori sono diversi da zero, mentre restituisce 0 se uno
dei due valori o entrambi sono uguali a zero (tabella 1).
Altri due operatori che lavorano a livello di bit sono ’«’ e ’»’, che potremmo
chiamare rispettivamente scivola a sinistra e scivola a destra. Il primo, ad es-
empio, converte l’intero che riceve nel suo inlet sinistro nella sua forma bi-
naria e aggiunge a destra tanti bit uguali zero quanti sono richiesti dall’inlet
di destra. Nella tabella 4 c’è un esempio con il numero 113 da spostare a
sinistra di due posizioni.

53
10 10

&&

Figure 50: l’operatore ’&& ’ confronta due valori in base alla tavolà di verità per
AND

113 = 1 1 1 0 0 0 1 <<
2 =
452 = 1 1 1 0 0 0 1 0 0

Table 4: scivola a sinistra di due posizioni

t b b

113 2

<<

452

Figure 51: La relativa patch di Pd che realizza lo scivolamento a sinistra

5.1.4 If

Per terminare il capitolo sulle istruzioni condizionali non resta che af-
frontare il costrutto if. Pd non dispone di un oggetto if, ma consente di
usare questo comando all’interno dell’oggetto expr che abbiamo già incon-
trato (sezione 3.3.2). Nei comuni linguaggi di programmazione l’istruzione

54
if valuta un’espressione, se vera restituisce un certo risultato, se falsa ne
restituisce un altro. Nel linguaggio C la sintassi del costrutto if è la seguente:

if (espressione)
fai una certa cosa;
else
fanne un’altra;

che significa: "Se l’espressione è vera fai una certa cosa, altrimenti fanne
un’altra". In Pd invece la sintassi è:

if (espressione, a se vera, b se falsa)

expr if ($f1 < 10, $f1 * 5, 10)

Figure 52: se il numero in entrata è minore di 10 espr restituisce il numero stesso


moltiplicato per 5, altrimenti restituisce 10

5.2 loops E ITERAZIONI

Le iterazioni in Pd si possono gestire in molti modi. Generalmente un’iterazione


nei linguaggi di programmazione è la ripetizione di un evento fino all’uscita
dall’evento stesso, determinata dal verificarsi di una certa condizione. In
Pd un’iterazione può essere l’emissione di un bang ogni mezzo secondo
per un numero definito di volte. Come sappiamo metro genera bang a ripe-
tizione, finché non viene spento. E’ semplice quindi inserire un contatore
che si occupa di contare i bang usciti e appena raggiungo il valore desider-
ato si occupa di spegnere metro. Osserviamo la patch in figura 53.
Pd implementa anche l’oggetto until che emette un numero di bang definito
da un numero in entrata nel suo inlet sinistro. A differenza della patch in
figura 53 until non è orientato al tempo ma opera quasi istantaneamente

55
1 0

metro 500

loadbang

float + 1

0 sel 9

Figure 53: la patch produce 10 bang attraverso un oggetto metro controllato da un


contatore e da un selettore

come nei tradizionali linguaggi di programmazione. In effetti until fun-


ziona secondo lo schema classico di un ciclo for del C:

for (i=0; i<100; i++)


espressione;

che significa: "finché il contatore, partito da 0 non arriva a 99, valuta


l’espressione". Se l’espressione fosse un ordine di stampare il valore della
variabile-contatore avremmo:

for (i=0; i<100; i++)


printf("%d", i);

Nella figura 54 si vede la patch di Pd che fa la stessa cosa.

56
100

until

loadbang

int + 1

print

Figure 54: ciclo until: valutare l’algoritmo con un click sulla message box in alto e
osservare il risultato nella Pd window

57
6 IL MIDI

6.1 PANORAMICA SUL PROTOCOLLO MIDI

Il protocollo MIDI (Musical Instrument Digital Interface) consente a dispos-


itivi diversi di comunicare fra loro attraverso l’invio messaggi che vengono
interpretati e tradotti. È a tutti gli effetti un protocollo di comunicazione,
quindi i messaggi sono formati esclusivamente da numeri. Il MIDI non
manipola, non invia, non riceve, né gestisce suoni di alcun tipo.
Anche se, tipicamente, il protocollo MIDI viene usato in ambito musicale,
teoricamente può essere utilizzato anche per altri scopi.
Affinché il MIDI possa funzionare è necessario che ci siano almeno due
dispositivi che devono comunicare e che siano fornite di porte di comuni-
cazione. Le porte di uscita dei messaggi sono le porte MIDI OUT, quelle
di entrata MIDI IN. C’è un altro tipo di porta, MIDI THRU che consente
di reindirizzare un messaggio in entrata da una MIDI IN verso un altro
dispositivo.
Praticamente un dispositivo che invia (Master) dati, indirizza i propri mes-
saggi attraverso la sua porta MIDI OUT. Il dispositivo ricevente (Slave) li
riceve attraverso la sua porta MIDI IN ed eventualmente li indirizza a sua
volta ad un altro SLAVE attraverso la sua MIDI THRU.
Questo schema logico non è l’unico possibile, ma in questa sede non ci
addentreremo oltre negli schemi di collegamento MIDI, anche perché con-
cettualmente lo schema appena illustrato è quello su cui si basano tutte le
possibili configurazioni.
Il MIDI è anche in grado di permettere la comunicazione fra dispositivi
software risiedenti su una stessa macchina, tipicamente un computer. Ad
esempio Pd potrebbe ricevere messaggi MIDI da un qualunque sequencer
e inviarli a sua volta alla scheda audio.

58
6.1.1 ANATOMIA DI UN MESSAGGIO MIDI

Il messaggi MIDI sono fondamentalmente costituiti da sequenze di due o


tre bytes, il primo dei quali è detto STATUS BYTE, gli altri DATA BYTE. Il
primo si distinuge dal secondo perché il bit più significativo (quello più a
sinistra) è uguale a 1:

10000000 (statys byte)


00000000 (data byte)

Lo STATUS BYTE è concettualmente diviso in due nibble, cioè gruppi di


quattro bit, il primo dei quali, quello a sinistra, contiene il bit più signi-
ficativo e altro tre bit che indicano il tipo di messaggio. Il secondo nibble
informa sul canale verso cui sarà inviato il messaggio.

Riassumendo, quindi, uno STATUS BYTE è costituito da 3 elementi infor-


mativi: il primo bit, che indica che lo STATUS BYTE è tale, 3 bit per il tipo
di messaggio e 4 bit per il canale o per un tipo particolare di messaggio
nel caso di un System Message. Poiché con quattro bit si possono avere 16
combinazioni diverse (0-15) un dispositivo MIDI può inviare e ricevere su
16 diversi canali.

I 3 bit di tipo di dato ci danno 8 possibili tipi diversi:

000 Note OFF


001 Note ON
010 Polyphonic Key Pressure
011 Control Change
100 Program Change
101 Channel Pressure
110 Pitch Bend Change
111 System Message

Un esempio. Una macchina master invia un messaggio come questo:

10010000

59
si tratta di uno STATUS BYTE (il bit più a sinistra è 1) che sta per inviari un
DATA BYTE di tipo Note ON (001) sul primo canale (0000). Abbreviando,
potremmo anche pensare a questo come lo STATUS BYTE 144, che è il byte
in question e convertito in decimale.

Un messaggio Note ON indica l’esecuzione di una nota, con un suo pitch,


cioè una sua altezza e una sua velocity cioè il suo volume (velocity rimanda
all’idea che la velocità con cui un tasto viene premuto è proporzionale al
volume che si ottiene)
Uno STATUS BYTE di Note On quindi sarà sempre seguito da due DATA
BYTE, ognuno dei quali può assumere un valore compreso fra 0 e 127.
Infatti il DATA BYTE, ha 7 bit a disposizione per informare (il primo bit
indica che il DATA BYTE è tale).

Riprendendo l’esempio precedente:

10010000 (STATUS BYTE Note ON sul canale 0)


00111100 (DATA BYTE Pitch 60)
01000000 (DATA BYTE Velocity 64)

Come già detto, uno STATUS BYTE può essere seguito da uno o due DATA
BYTE. Ad esempio, un messaggio di Program Change (100), che serve ad
impostare o cambiare il timbro per una determinata sequenza di eventi
MIDI, il DATA BYTE è soltanto uno.
Nel caso di un un System Message, codice 111, i 4 bit a destra dello STATUS
BYTE non rappresentano il canale, ma, appunto, il codice di un particolare
messaggio detto messaggio di sistema, inviato a tutto il sistema per dare
informazioni generali. Gli altri sono detti Channel Voice Messages.
La struttura quindi della comunicazione MIDI è quindi molto semplice.
Uno STATUS BYTE indica il tipo di messaggio inviato, uno o due DATA
BYTE portano i dati del tipo di messaggio. Per maggiori informazioni sui
tipi di messaggio la rete è un’ottima fonte di informazioni.

6.2 P D E IL MIDI

Pd può ricevere e inviare messaggi MIDI. Dal menu MIDI settings (che si
apre da Media o da preferences, in base al sistema operativo utilizzato) è
possibile impostare le porte di entrata e di uscita dei messaggi MIDI.

60
6.2.1 MIDIIN E MIDIANALYZE

L’oggetto che ci consente di far entrare in Pd messaggi MIDI puri, cioè an-
cora non codoficati in base al tipo è midiin che manda fuori dall’outlet di
sinistra messaggi Channel Voice in forma decimale. In sostanza restituisce
sequenze di numeri interi compresi fra 0 e 239 poiché gli STATUS BYTE di
tipo SYSYTEM MESSAGE, che sono compresi fra 240 e 255 non vengono
catturati.

Ora proviamo a implementare un oggetto, midianalyze che analizza i dati


ricevuti da midiin convogliandoli a vari inlet in base al loro significato.
Tale oggetto esiste già in una forma quasi uguale nella libreria che emula
gli oggetti di Max/MSP e prende il nome di midiparse.
midianalyze (fig. 55) non ha inlet in quanto contiene al suo interno l’oggetto
midiin che riceve messaggi midi dall’esterno di Pd. Ha invece 6 outlets,
il primo dei quali restituisce messaggi di noteON, il secondo di Channel
Pressure, il terzo di Control Change, il quarto di Program Change, il quinto
di Channel Pressure e l’ultimo di Pitch Bend. Sono esclusi i messaggi di
note OFF perché sono ormai inutilizzati dal protocollo. Per chiudere una
nota infatti si usa un normale messaggio di Note ON con velocity pari a
zero. Ogni outlet formatta i messaggi restituendo una lista composta da i
dati e dal numero del canale.
midianalyze

prepend set prepend set prepend set prepend set prepend set prepend set

45 0 0 10 74 0 16 40 0 42 0 51 9 0 53 0
NoteON keypressure controlchange programchange channelpressure pitchbend

Figure 55: midianalyze e i suoi outlets

L’interno dell’abstraction (fig. 56) è semplice, l’oggetto midiin invia i mes-


saggi all’oggetto moses che li divide fra i suoi due outlet: se un messaggo
(che, ricordiamo non è altro che un byte in forma decimale) è inferiore a
128 (0-127) sarà inviato al primo outlet in quanto si tratterà di un DATA
BYTE, al contrario sarà uno STATUS BYTE e sarà inviato all’altro outlet
moses smista i messaggi inviandoli a sei subpatches, ognuna delle quali
costruirà la lista appropriata. I messaggi di Program Change e di Chan-
nel pressure saranno formati da una lista di due interi: il dato e il canale,

61
midiin

moses 128

pd noteon pd keypressure pd cc pd pgmchange pd chnpressure pd pitchbend

outlet noteon outlet keypressure outlet cc outlet pgmchange outlet chnpressure outlet pitchbend

Figure 56: L’interno dimidianalyze

tutti gli altri messaggi saranno formati da una lista di tre interi, due per i
dati, uno per il canale.

In figura (fig. 57) è mostrata la subpatch che interpreta e resistuisce la lista


dei messaggi di Program Change. Se lo STATUS BYTE è compreso fra
192 e 207, l’algoritmo fa un AND restituendo 1 se entrambe le condizioni
sono soddisfatte e zero in ogni altro caso. In caso positivo l’oggetto spigot,
ricevendo 1, permette al DATA BYTE ricevuto di uscire dal suo outlet e di
entrare in list append, dove verrà unito al numero di canale.

inlet data inlet status

t f f f

>= 192 <= 207 - 192

&&

spigot

list append

outlet pgmchange

Figure 57: La subpatch che formatta la lista dei messaggi Program Change

Il caso di un messaggio Note ON (fig. 58) è un po’ più complesso perché


la lista è formata da 3 interi. I dati che spigot lascia passare vengono prima
passati per list prepend che, ricorsivamente, li mette in lista per inserirli poi

62
nell’inlet destro di list append. Non appena la lista raggiunge i due elementi
(list length si occupa di contare gli elementi di una lista) tramite sel 2 viene
emesso un bang che fa uscire la lista e permette che questa venga unita al
terzo elemento, cioè il numero del canale.

inlet data inlet status

t f f f

>= 144 <= 159 - 144

&&

t f b

spigot

list prepend t l

t l l

list length

sel 2

list append

list append

outlet noteon

Figure 58: La subpatch che restituisce la lista dei messaggi Note ON

Tutte le altre subpatches dell’oggetto midianalyze funzionano come quelle


che abbiamo appena analizzato. Lasciamo al lettore la possibilità di ri-
costruirle.

6.2.2 ALTRI OGGETTI MIDI

Una volta capito il funzionamendo dei messaggi MIDI ed aver implemen-


tato l’oggetto midianalyze non ci sarà bisogno di soffermarsi troppo sugli

63
oggetti che in Pd si occupano del MIDI. Nella maggioranza dei casi gli
oggetti avranno una versione per l’input dei dati e una per l’output. Ne
diamo di seguito un elenco (parziale):

oggetti descrizione
midiin/midiout dati MIDI grezzi
notein/noteout Note ON
pgmin/pgmout Program Change
bendin/bendout Pitch Bend
ctlin/ctlout Control Change
touchin/touchout Channel Pressure
polytouchin/polytouchout Polyphonic Key Pressure

Oltre a tali oggetti, ce ne sono altri legati alla gestione di eventi MIDI.
Esaminiamo due oggetti, uno per la manipolazione di eventi Note ON in
entrata, un altro per gli stessi tipi di eventi in uscita.

L’oggetto stripnote riceve coppie di valori (pitch,velocity) e lascia passare


sltanto quelle coppie che hanno velocity diversa da zero. Può essere utile
quando è necessario processare soltanto le altezze, evitando così la ripe-
tizione del pitch. Infatti ogni volta che un messaggio note ON è ricevuto, è
seguito sempre da un altro messaggio, con lo stesso pitch, ma con velocity
uguale a zero. Piuttosto che fare un esempio di uso di stripnote, proviamo
ad implementare un oggetto che faccia la stessa cosa (fig. 59).
L’oggetto makenote riceve coppie di valori (pitch,velocity), li fa uscire e ag-
giunge un messaggio con lo stesso pitch, ma con velocity uguale a zero.
In pratica chiude un evento Note ON. Può avere due argomenti: velocity
iniziale e durata della nota.
Un esempio di makenote sarà spiegato nella prossima sezione, dove verrà
implementata una versione del brano di Steve Reich Piano Phase.

6.3 U N ESEMPIO DI EDITING ALGORITMICO MIDI

Nel 1967 il compositore americano Steve Reich compose un brano per due
pianoforti intitolato Piano Phase che esplorava la tecnica del dephasing.
Un pattern di 12 semicrome viene eseguito all’unisono e in ostinato dai due
pianisti. Dopo un certo numero di ripetizioni il secondo pianista aumenta
leggermente la velocitù in modo da produrre una sfasatura fra le due frasi,

64
60 64

60 0

70 25

unpack 0 0

t f f

!= 0

t f f

moses 1

spigot

print pitch print vel

Figure 59: L’oggetto clone di stripnote

sfasatura che si allarga fino a far si che i due pattern non si ritorvano di
nuovo sovrapposti esattamente, ma ad una nota di distanza. I due pianisti
a questo punto suonano per un po’ allo stesso tempo per poi ricominciare il
processo, fino a che, completato il giro di tutte e 12 le note, non si ritrovano
all’unisono. A quel punto il primo pianista viene lasciato solo per un po’ e
inizia la seconda parte del brano, della quale non ci occuperemo.

Per implementare tale algoritmo è necessario formalizzare il problema. La


questione principale da risolvere è data dal fatto che, mentre uno dei pi-
anisti suona a velocità costante (avremo, intuitivamente, un oggetto metro
che non cambia mai, il secondo pianista suona alla stessa velocità del primo
per un po’, poi accelera per sfasare i pattern poi torna alla velocità iniziale
non appena i pattern non sono sovrapposti esattamente a una nota di dis-
tanza.

Bisogna quindi stabilire:

65
• quanti pattern i pianisti suonano allo stesso tempo;

• qual’è il tempo costante;

• qual’è il tempo del secondo pianista che produce la sfasatura;

• quanti pattern sono necessari perché i pattern si reincontrino esatta-


mente a una nota di distanza;

Convenzionalmente scegliamo che i pianisti suoneranno quattro pattern


allo stesso tempo, poi il secondo pianista inizierà a suonare più veloce-
mente. Se suonasse ogni nota 1 millesimo di secondo più velocemente
del primo, alla fine del suo pattern avrà guadagnato 12 millisecondi. Per
semplicità quindi assumiamo che ogni durata del primo pianista sarà un
multiplo di 12, per esempio 144 millisecondi. In questo modo dopo 12
esecuzioni del pattern i due si ritrovano nuovamente in fase.
Riassumendo:

• 4 pattern in fase con durata di 144 ms per nota

• 12 pattern dove il primo pianista suona a 144 ms e il secondo a 143


ms

• il ciclo ricomincia a una nota di distanza.

Pima di tutto implementiamo la sequenza a velocità costante (fig. 60).


L’oggetto metro è collegato ad un contatore che enumera le 12 note del pat-
tern, ovviamente espresse in altezze MIDI. L’oggetto list-nth riceve la lista
delle altezze e nel suo inlet destro l’indice della lista da far uscire dall’outlet.
Infine makenote formatterà ogni altezza in modo che abbia velocity pari a 64
e durata di 120 ms.
Come detto, il secondo pianista suonerà la stessa cosa, variando però la ve-
locità. L’algoritmo sarà identico (fig. 60) cln le sole differenze che l’inlet de-
stro di metro ospita le due possibili velocità di esecuzione e che l’oggetto no-
teout invierà i dati al secondo pianoforte, sul secondo canale MIDI. Saranno
quindi caricati nell’eventuale gestore dei suoni due pianoforti, uno sul
primo, l’altro sul secondo canale.
Infine la parte più interessante dell’algoritmo. Un contatore (fig. 62) enu-
mera ogni pattern del pianista di sinistra, con modulo 16, in modo da
contare da 0 a 15. Un selettore poi emette un bang quando il contatore

66
t f b

metro 144

f 0 + 1

% 12

t b f

64 66 71 73 74 66 64 73 71 66 74 73

list-nth

makenote 64 120

noteout 1

Figure 60: La sequenza a velocità costante

raggiunge lo zero e il 4, cioè l’inizio della parte in fase e l’inizio di quella a


velocità diverse. Quando il selettore banga in corrispondenza di uno zero
in entrata, metro riceve 144 nel suo inlet destro. Quando invece c’è il 4 metro
viene settato a 143 finché il contatore non torna a zero.
L’algoritmo così è concluso, ma se lo eseguiamo ci rendiamo conto che
l’esecuzione è molto poco umana. Proviamo a modificare la patch in modo
che ogni nota abbia una velocity leggermente diversa (fig. ??). Il risultato
che si ottiene è leggermente più realistico.
Allo stesso modo si possono fare altre migliorie, come ad esempio ac-
centare alcune note del pattern, aumentare il range dinamico, o inserire
il pedale di risonanza (che è gestito dal controller 64 dello standard MIDI
con un normale messaggio di tipo Control Change) e altro, ma lasciamo al
lettore il divertimento di sperimentare eventuali modifiche alla patch.

67
144 143

t f b t f b

metro 144 metro 144

0 0

f 0 + 1 f 0 + 1

% 12 % 12

t b f t b f

64 66 71 73 74 66 64 73 71 66 74 73 64 66 71 73 74 66 64 73 71 66 74 73

list-nth list-nth

makenote 64 120 makenote 64 120

noteout 1 noteout 2

Figure 61: I due pianisti virtuali di Piano Phase

68
reset counter
0
t f b sel 0

metro 144
f 0 + 1

0
% 16

f 0 + 1 sel 0 4

% 12 144 143

t b f t f b

metro 144
64 66 71 73 74 66 64 73 71 66 74 73

list-nth 0

makenote 64 120 f 0 + 1

noteout 1 % 12

t b f

64 66 71 73 74 66 64 73 71 66 74 73

list-nth

makenote 64 120

noteout 2

Figure 62: Il contatore che regola la velocità di esecuzione del pattern

69
reset counter
0
t f b sel 0

metro 144
f 0 + 1

0
% 16

f 0 + 1 sel 0 4

% 12 144 143

t b f b t f b

metro 144
64 66 71 73 74 66 64 73 71 66 74 73

list-nth random 32 0

+ 48 f 0 + 1

% 12
makenote 64 120
t b f b
noteout 1

64 66 71 73 74 66 64 73 71 66 74 73

list-nth random 32

+ 48

makenote 64 120

noteout 2

Figure 63: La sequenza a velocità costante

70
7 OGGETTI GUI

Nel corso dei nostri primi esperimenti abbiamo già avuto modo di incon-
trare alcuni oggetti grafici, che nell’ambito del mondo informatico sono
dette GUI (graphical user interfaces). Pd mette a disposizione un certo nu-
mero di GUI’s, alcuni nativi, cioè facenti parte del pacchetto standard del
programma, altri derivati da librerie esterne, la maggior parte delle quali
sono caricate nella versione extended. Genericamente possiamo dire che
tutte le GUI di Pd possono essere configurate tramite le properties, accessi-
bili col tasto destro del mouse sulla GUI stessa.

Le GUI native di Pd sono:

- bang

- toggle

- slider orizzontali e verticali

- radio button orizzontali e verticali

- VU-meter

- canvas

- number2

Sul bang non c’è molto altro da dire, lo abbiamo incontrato già moltissime
volte. toggle invece è un oggetto molto utile che permette di restituire 1
quando è attivo, 0 quando è disattivo. Praticamente è una variabile binaria
che si attiva con un click del mouse. Quando è attivato mostra una croce
all’interno del quadrato che la costituisce (figura 64).

Pd offre due tipi di slider, che sono delle leve attivabili con il mouse o da
altri oggetti. Fra le due non c’è alcuna differenza se non nel fatto che un

71
tipo è verticale, l’altro orizzontale. Dalle proprietà si può impostare la
dimensione, ma soprattutto il range dell’output.

1 0

metro 500

int 1 + 1

mod 2

sel 0

Figure 64: l’oggetto toggle

Nella figura 64 il toggle più grande attiva un oggetto metro che a sua volta
manda dei bang a un contatore che attraverso l’oggetto mod conta solo da
0 a 1, quando è 0, il bang (grazie all’oggetto sel) esce da sinistra, quando
è 1 esce a destra. Nella figura successiva invece (fig. 65) lo slider verticale
di sinistra pilota gli altri due: quello di destra attraverso expr effettua il
movimento contrario, mentre quello di sotto si muove in parallelo, ma som-
mato a un movimento continuo generato dall’algoritmo a sinistra. metro
attiva un contatore da 0 a 1. Il valore in uscita viene moltiplicato per un
altro valore che va da 0 a 20, gestito dallo slider principale. Il prodotto
di questi due fattori diventa il valore-obiettivo dell’oggetto line che crea il
movimento dello slider in basso. C’è da notare che ci sono due oggetti ’r’,
cioè receive, ma non c’è nessun send! Le GUI infatti possono mandare o rice-
vere messaggi senza bisogno di creare oggetti e supplementari. Possiedono
degli oggetti send e receive incorporati che possono essere impostati dalle

72
r slide
metro 100
expr ($f1 / 127) * 20
int 1 + 1

mod 2
r slide

* 10 manovrare_da_qui expr (127 - $i1)

$1 90

line

Figure 65: lo slider verticale a sinistra pilota gli altri due

properties della GUI stessa.

I radio button sono oggetti formati da barrette orizzontali o verticali cos-


tituite da caselle ordinate. L’uscita è il numero della casella a partire da
quella più a sinistra nel caso di radio button orizzontali, e da quella più in
alto nel caso di verticali. Ricordiamo che il conteggio inizia dallo 0, quindi
un radio button di 16 elementi, avrà un output che va da 0 a 15. In figura
66 due radio button disegnano un grafico. Unica annotazione, i valori del
radio button verticale vengono invertiti per consentire un migliore adesione

73
al grafico, così il primo valore in alto diventa 9 in luogo di zero, il secondo
8 invece che 1, etc. . . .
array1

r ordinata

expr (9 - $i1) r ascissa

tabwrite array1

Figure 66: impostare prima l’indice (radio button) orizzontale, poi il valore con
quello verticale

74
Della GUI VU-meter avremo modo di scrivere nella parte che riguarda
l’audio, mentre possiamo ora accennare alle canvas che sono oggetti sem-
plici che servono a connotare graficamente le nostre patch in modo da
caratterizzare con i colori alcune zone della finestra. Possono essere utili
in patch molto articolate dove c’è bisogno di rendere riconoscibili le varie
parti dell’algoritmo. Infine l’oggetto number2 è molto simile alla normale
number box con qualche possibilità in più di configurazione grafica.

7.1 A LTRE GUI DALLE LIBRERIE DI P D

Oltre alle GUI native che abbiamo appena discusso, diamo ora una panoram-
ica veloce di alcune altre GUI introdotte con le nuove librerie:

- grid

- gcanvas

- knob

- envgen

grid e gcanvas sono molto simili, sono due griglie bidimensionali che emet-
tono la posizione del mouse (x, y) dai due outlet alla pressione di quest’ultimo.
knob è la classica manopola tipo sintetizzatore analogico. Ha un’unica us-
cita che emette l’output nel range impostato nelle properties. Infine l’oggetto
envgen è un envelope generator che emette dati in un formato compatibile
con la versione audio di line, cioè line∼ , del quale tratteremo approfondi-
tamente nella parte di questo manuale dedicata all’audio.

Prima di concludere questo capitolo, va ricordato che l’uso massiccio di


GUI nelle patch è sconsigliato. La grafica vettoriale che sta alla base di
tali oggetti può rallentare la capacità di calcolo quindi quando è possibile
evitarne l’uso, si eviti. Ad esempio in luogo dei bang grafici si cerchi di
usare l’oggetto relativo bang o ’b’. Non è importante la bellezza estetica di
una patch quanto la sua chiarezza, quindi è meglio evitare troppi oggetti
grafici e abbondare, al contrario, di subpatches e annidamenti.

75
Part II

AUDIO
8 L’A U D I O D I G I T A L E

8.1 L’ OSCILLATORE

Il suono più semplice che può essere prodotto sinteticamente è quello gen-
erato da un oscillatore. Nel mondo analogico un oscillatore è un circuito che
genera forme d’onda di vari tipi, anche se generalmente se non si specifica
altro si parla di oscillatore intendendo un generatore di onde sinusoidali.
Un’ onda sinusoidale è un’onda generata da una funzione sinusoidale (vedi
fig. 67), che si può esprimere tramite la formula:

y = A sin(2π f x + φ)

dove A è l’ampiezza dell’onda, tipicamente impostata ad 1, quindi i valori


della funzione oscillano fra 1 e -1, 2π f = 2π τ è la frequenza angolare che
indica quanti periodi ci sono in un intervallo di 2π, f = τ1 è la frequenza,
che indica quante volte la funzione si ripete nell’unità di tempo, φ è la fase,
cioè lo scartamento che la funzione subisce, ovvero il parametro che perme-
tte di anticipare o ritardare i valori della funzione1 .

Per produrre una sinusoide con un calcolatore è necessario fare uso di un


oscillatore digitale, un algoritmo che produca i valori della funzione sinu-
soidale, ossia delle ampiezze dell’onda. A differenza di un segnale elettrico,
che è continuo, il calcolatore può solo produrre segnali discreti, quindi
l’oscillatore digitale calcola i valori della funzione il numero delle volte in-
dicato dalla frequenza di campionamento. Ad esempio se la frequenza di
campionamento è 44100 hertz, l’oscillatore calcola i valori della funziona
44100 volte al secondo. Questa frequenza di campionamento approssimerà
la forma d’onda desiderata, pur non riuscendo a costruirne una identica a
quella analogica (fig. 68).

1 http://it.wikipedia.org/wiki/Sinusoide

77
Parametri di una sinusoide

2
1

1
ampiezza
0

0
−1

−1
−2

−2
tempo

Figure 67: il grafico di una funzione sinusoidale

In Pd l’oscillatore digitale è implementato nell’oggetto osc∼. Nella patch


in figura 69 l’oscillatore produce una sinusoide di 440 hz che l’oggetto
dac∼ converte in segnale analogico, in modo da poter essere inviata agli
altoparlanti.
In genere comunque oscillatori digitali non calcolano i valori della fun-
zione sinusoidale in tempo reale, ma usano un sistema che rende le cose
più veloci. Piuttosto che fare 44100 calcoli di funzioni sinusoidali al sec-
ondo è preferibile leggere delle tabelle che hanno i valori di una fun-
zione sinuoidali già pronti. Piuttosto che calcolare, leggere dei dati è
un’operazione molto più rapida. Nella wavetable quindi c’è l’elenco dei
valori di ampiezza indicizzati di un ciclo di forma d’onda, l’oscillatore
non deve fare altro che leggerli uno ad uno, iniziando dal primo (0) fino
all’ultimo. La tabella può avere dimensioni arbitrarie: più è alto il numero
dei punti più accurata è l’onda risultante. In figura 70 è mostrata la rap-
presentazione grafica di una wavetable: sull’asse delle ascisse c’è l’indice,
su quella delle ordinate il valore di ampiezza. Nella memoria del vet-
tore che contiene il grafico ci saranno quindi delle coppie di valori (indice,
ampiezza). In questo caso avremo (0, 0), (1, 0.3125), (2, 0.5748), (3, 0.6885),
...
L’oggetto osc∼ legge una cosinusoide scritta in una wavetable di 512 punti.
La cosinusoide graficamente è identica ad una sinusoide, con l’unica dif-

78
Sinusoide digitale

1.0

1.0
0.5

0.5
ampiezza
0.0

0.0
−0.5

−0.5
−1.0

−1.0
tempo

Figure 68: il grafico di una funzione sinusoidale prodotta da un calcolatore

osc~ 440

dac~

Figure 69: l’oscillatore di Pd

ferenza che la sinusoide ha come primo valore 0, mentre la cosinusoide 1,


quindi è sfasata rispetto alla prima di π2 (vedi fig. 71).
L’oggetto tabosc4∼ implementa un lettore di wavetable generiche, dove è
possibile disegnare una forma d’onda qualunque e sceglierne la dimen-
sione. Di tale oggetto si farà larghissimo uso nelle sezioni successive del
presente manuale.

8.1.1 FREQUENZA E AMPIEZZA DEL SEGNALE

L’onda sinusoidale è un’onda periodica perché la sua forma si ripete iden-


tica ad intervalli di tempo regolari. Il periodo è quindi il tempo neces-

79
0 1 2 3
Wavetable
4 5 6 7 8 9 10

1.0

1.0

● ●
● ●

● ●

0.5

0.5
● ●
ampiezza
0.0

0.0
−0.5 ● ●

−0.5
0 1 2 3 4 5 6 7 8 9 10

index

Figure 70: una cosinusoide

sario affinché l’onda compia un intero ciclo. Le oscillazioni dell’onda si


alternano fra il campo positivo e quello negativo. Se prendiamo come
punto di riferimento il picco positivo dell’onda, la lunghezza d’onda sarà la
distanza (λ) fra tale picco e il successivo. Questo valore è inversamente
proporzionale alla frequenza dell’onda, maggiore sarà λ, minore sarà la fre-
quenza, ovvero il numero di cicli completi dell’onda per secondo. Questo
valore si misura in hertz (vedi fig. 72).
Perché generi un segnale udibile dall’orecchio umano, l’onda deve avere
una frequenza compresa circa fra 20 e 20000 hertz. Tale range costituisce la
banda udibile.
Quando si parla genericamente dell’ampiezza del segnale si intende in-
vece il picco massimo di ampiezza raggiunto dall’onda, cioè la distanza
maggiore dal punto di quiete (ovvero zero). Più specificamente si tratta
dell’ampiezza di picco dell’onda, mentre si parla di ampiezza istantanea quando
si tratta di un campione qualsiasi dell’onda. La massima ampiezza di un
segnale è 1, superato tale limite il segnale distorce.
La frequenza è responsabile della percezione dell’altezza, mentre l’ampiezza
dell’intensità del segnale.

80
Cosinusoide

1.0

1.0
0.5

0.5
ampiezza
0.0

0.0
−0.5

−0.5
−1.0

−1.0
tempo

Figure 71: una cosinusoide

Parametri di una sinusoide


2

2
τ ➤ λ
➤❘

➤❘



1

1
➤ ❘
ampiezza

A
➤ ❘
0

0
−1

−1
−2

−2

tempo

Figure 72: parametri di una forma d’onda. A = ampiezza, τ = periodo, λ =


lunghezza d’onda

8.1.2 osc∼

L’object box osc∼ implementa un oscillatore digitale. Accetta come argo-


mento interno la frequenza (fig. 69) il cui valore può anche essere variato

81
dall’inlet di sinistra (fig. 73). Come vedremo successivamente oltre che
dati, l’inlet di sinistra accetta anche segnali per controllare la frequenza.

242

osc~ 200

dac~

Figure 73: l’oggetto osc∼ con frequenza controllata da una number box

Nella patch in figura 74 un oggetto line permette di realizzare un glissando,


cioè uno scivolamento da una frequenza ad un’altra, facendo udire tutte le
frequenze intermedie. In questo caso il glissando parte da 20 hz e giunge
a 1000 hz in 5 secondi.

20, 1000 5000

line

osc~ 20

dac~

Figure 74: la realizzazione di un glissando con l’oggetto line

Volendo invece intervenire sull’ampiezza del segnale, è necessario utiliz-


zare un moltiplicatore, come un oggetto *∼, per moltiplicare l’ampiezza
istantanea del segnale per un fattore costante (o variabile). In figura 75
l’oggetto *∼ moltiplica per 0.5 il segnale in entrata, dimezzandone l’ampiezza.
L’ampiezza di picco del segnale in uscita sarà quindi di 0.5. In figura 76
è mostrata un’onda con ampiezza di picco 1, e una con ampiezza di picco
0.5.

82
osc~ 440

*~ 0.5

dac~

Figure 75: la realizzazione di un glissando con l’oggetto line


1.0

1.0
0.5

0.5
a)
0.0

0.0
−0.5

−0.5
1.0 −1.0

1.0 −1.0
0.5

0.5

b)
0.0

0.0
−0.5

−0.5
−1.0

−1.0

Figure 76: la realizzazione di un glissando con l’oggetto line

Come per la frequenza, si può controllare l’ampiezza interattivamente, con


dati o segnali di controllo. Nel caso in figura 77 una slider verticale emette
valori compresi fra 0 e 1, i quali entrano in line. line emette i valori in
entrata scivolando con rampe di 20 millisecondi fra un valore e il precedente

83
per evitare che l’ampiezza cambi troppo repentinamente producendo un
effetto scalino.
amp
osc~ 440

*~ 0.5

dac~
$1 20

line

Figure 77: la realizzazione di un glissando con l’oggetto line

8.1.3 tabwrite∼

Un oggetto molto utile è tabwrite∼ che consente di scrivere i valori di


un segnale in una tabella. In questo caso lo utilizziamo per mostrare la
forma d’onda di un segnale al variare dell’ampiezza e della frequenza. In
figura 78 l’oggetto tabwrite∼ scrive i valori ricevuti in una tabella (amp)
ogni volta che riceve un bang. metro emette un bang ogni 100 millisecondi
producendo l’impressione dell’onda in movimento. Gli oggetti send∼ e
receive∼ sono come send e receive per i dati, ma inviano e ricevono seg-
nale.

8.1.4 LA RAPPRESENTAZIONE DEL SUONO

Attraverso l’oggetto tabwrite∼ possiamo avere una rappresentazione del


segnale nel dominio del tempo, ovvero in ogni istante di tempo viene dis-
egnato un punto in corrispondenza dell’ampiezza del segnale. Il risultato
di tale operazione permette di visualizzare la forma d’onda.
In figura 79 è rappresentato un ciclo di un’onda periodica complessa, for-
mata dalla somma di 3 sinusoidi. Come già detto questa rappresentazione
mostra l’ampiezza in funzione del tempo, ma non da alcuna informazione
riguardo la frequenza del segnale. Per ottenere informazioni su un suono
complesso è necessario scomporlo nelle sue componenti semplici e rapp-
resentare ogni singola frequenza. Attraverso algoritmi che operano tali
scomposizioni è possibile analizzare lo spettro di un suono, cioè la sua

84
amp
883
r~ sig
metro 100
osc~ 440
tabwrite~ amp
*~ 0.5 amp

dac~
$1 20
send~ sig
line

Figure 78: la realizzazione di un glissando con l’oggetto line

rappresentazione nel dominio della frequenza. L’analisi dello spettro può


essere visualizzata in modi molto diversi, anche se fondamentalmente ci
sono 2 tipi di analizzatori di spettro:

- gli analizzatori di ampiezza in funzione della frequenza

- gli analizzatori di ampiezza e frequenza in funzione del tempo

Nel primo caso (fig. 80) si ha un grafico bidimensionale nel quale vengono
rappresentate la frequenza e l’ampiezza del suono in un dato momento.
Questa rappresentazione ha il limite di non poter dare una visione del
suono nella dimensione temporale, ma si riferisce ha un istante di tempo
oppure ad un suono che non varia in funzione del tempo. L’invariabilità
del suono in funzione del tempo esiste solo nei segnali prodotti digital-
mente (probabilmente nemmeno un suono elettrico analogico resta sem-
pre identico a se stesso). Nel mondo reale i suoni variano continuamente,
quindi una rappreentazione che non tenga conto della funzione tempo ha
valore solo in determinate circostanze.
Gli analizzatori del secondo tipo permettono di dare una visione più det-
tagliata e pertinente del suono perché rappresentano l’ampiezza e la fre-
quenza in funzione del tempo. La necessità di rappresentare 3 parametri
obbliga ad usare un grafico tridimensionale oppure a gestire uno dei tre
parametri in modo diverso. Nel caso mostrato in figura 81 c’è il tempo
sull’asse delle ascisse e la frequenza su quella delle ordinate, mentre l’ampiezza

85
Rappresentazione della forma d’onda

0.5

0.5
ampiezza
0.0

0.0
−0.5

−0.5
tempo

Figure 79: forma d’ondarisultante dalla somma di 3 sinusoidi

Spettrogramma ampiezza/frequenza
ampiezza

0 100 200 300 400 500 600 700 800 900 1000

frequenza

Figure 80: analizzatore di spettro bidimensionale, sull’asse delle ascisse c’è la fre-
quenza, su quella delle ordinate l’ampiezza. Il suono è costituito dalla
somma di onde di frequenza pari a 400, 700 e 800 hz

è rappresentata dal colore delle linee: nero per la massima ampiezza e varie

86
tonalità di grigio per ampiezza minore, fino al bianco, quando c’è assenza
di suono.

Spettrogramma ampiezza/frequenza/tempo

1000

1000
800

800
frequenza
600

600
400

400
200

200
0

0
tempo

Figure 81: l’ampiezza delle sinusoidi è rappresentata dal-l’intensità del colore


delle linee

8.2 L E FORME D ’ ONDA

Oltre alla forma d’onda più semplice, quella sinusoidale, che abbiamo esam-
inato nella sezione precedente, esistono altre forme d’onda periodiche. Il
loro numero è teoricamente infinito, anche se esistono alcune forme d’onda
classiche che si possono ottenere dalla somma di sinusoidi semplici in rap-
porto armonico fra loro.
Forme d’onda classiche sono l’onda quadra, l’onda triangolare e l’onda a
dente di sega che esamineremo fra poco.

8.2.1 tabosc4∼

Nella sezione 8.1 abbiamo menzionato l’oggetto tabosc∼ che legge la


forma d’onda da una tabella-vettore. Questo oggetto ci permette di trasfor-
mare in segnale dei vettori che contengono forme d’onda diverse dalla
sinusoide ordinaria. Per mettere in funzione tabosc∼ è necessario:

- creare un vettore di 2n + 3 punti

87
- riempire il vettore con i valori desiderati

- creare l’oggetto tabosc∼ con il nome del vettore come argomento

- usare l’inlet di sinistra per impostare la frequenza dell’oscillatore

Per i primi due punti si rimanda al capitolo 4. Per il resto si esamini


la patch in figura 82: l’oggetto tabosc∼ legge i dati dal vettore chiamato
sinead una frequenza di 400 hz e invia tutto a dac∼, ma anche a tabwrite∼
che mostra la forma d’onda ottenuta.
frq sine
0

tabosc4~ sine

amp

$1 20
wave
line

*~
start

metro 100

dac~ tabwrite~ wave

Figure 82: l’uso di tabosc∼ per leggere un vettore con una forma d’onda sinu-
soidale

Nei prossimi paragrafi mostreremo l’uso di tabosc∼ per forme d’onda


diverse.

8.2.2 ONDA QUADRA

Quella quadra é una forma d’onda che alterna solo due valori, general-
mente 1 e -1, ma anche 1 e 0 se si usa come segnale di controllo.

88
Onda quadra

2
1

1
ampiezza
0

0
−1

−1
−2

−2
tempo

Figure 83: un’onda quadra che alterna i valori 1 e -1

Secondo il Teorema di Fourier, un qualsiasi suono complesso periodico


può essere ottenuto dalla somma di sinusoidi in rapporto armonico fra
loro. Come abbiamo imparato dal capitolo sui vettori (4 possiamo dis-
egnare in un vettore una forma d’onda ottenuta dalla somma di sinu-
soidi tramite il comando sinesum. L’onda quadra si ottiene dalla somma
degli armonici dispari con ampiezza inversamente proporzionale al nu-
mero d’ordine dell’armonico, schematizzando:

arm 1 arm 2 arm 3 arm 4 arm 5 arm 6 arm 7


1 1 1
1 0 3 0 5 0 7

L’oggetto tabosc4∼ può essere usato per implementare un’onda quadra


scritta in un vettore tramite il comando sinesum. E’ sufficiente usare una
message box con il comando sinesum e scrivere tutti i valori di ampiezza
delle varie armoniche. In alternativa é possibile costruire un algoritmo
per disegnare la forma d’onda nel vettore. In figura 84 ci sono 3 forme
d’onda diverse, due realizzate con il comando sinesum, una con un algo-
ritmo. Il risultato visivo sono 3 onde diverse, le prime sono due forme
d’onda quadra approssimativa, infatti nel caso del vettore quadra9 sono stati
usati 9 armonici, nel secondo caso 40: più aumenta il numero degli ar-

89
monici, maggiore sarà la precisione della forma dell’onda. Nel terzo caso
l’onda é perfettamente quadrata.
Se si ascoltano le 3 onde (il messaggio set seguito dal nome di un’array
consente di cambiare il vettore da leggere con tabosc∼) si noteranno delle
differenze. Nel caso del vettore quadra9 il suono sarà meno ricco di ar-
monici di quello di quadra40, che a sua volta é meno ricco di quello di
quadralg.
0 quadra9 quadra40

set quadra40

set quadra9

set quadralg

tabosc4~ quadra9

;
quadra9 sinesum 512 1 0 0.33 0 0.2 0 0.1428 0 0.1111;
quadra9 normalize 1
dac~
;
quadra40 sinesum 512 1 0 0.33 0 0.2 0 0.1428 0 0.1111 0
0.0909 0 0.0769 0 0.0666 0 0.0588 0 0.0526 0 0.0476 0
0.0434 0 0.04 0 0.037 0 0.0344 0 0.0322 0 0.0303 0 0.0285 0
0.027 0 0.0256 0;
quadra40 normalize 1

quadralg
515
reset
until 0

int 0 + 1

expr if (($f1 < 256), 1, -1)

tabwrite quadralg

Figure 84: tre tipi diversi di onda quadra

PULSE WIDTH MODULATION (PWM)

I due modi che abbiamo usato nella sezione precedente per generare un’onda
quadra non sono gli unici possibili. Un altro sistema infatti è quello di in-
tervenire direttamente su un segnale sinusoidale e modificarlo in tempo
reale. Nella patch di figura 85 il segnale di osc∼ entra in expr∼ che genera
un’onda quadra con un semplice ciclo if: se i valori sono positivi, esce 1,
altrimenti esce -1.
L’oggetto expr∼ è l’omologo di expr per i segnali. Oltre a operare sulle
solite variabili numeriche ($fn o $in) può processare direttamente segnale.

90
150 wave

osc~ 200

expr~ if (($v1 > 0), 1, -1)

metro 100
dac~
tabwrite~ wave

Figure 85: onda quadra generata mediante intervento diretto su un segnale sinu-
soidale

Il simbolo per le variabili-segnale è $vn.

Questo modo di produrre un’onda quadra non è certo il più economico


dal punto di vista computazionale, ma consente di fare qualcosa che con
i sistemi precedenti era complicato, cioè intervenire in tempo reale sulla
forma dell’onda. Un’onda quadra è simmetrica, come del resto quella si-
nusoidale. Ai valori positivi rispondono valori negativi, quindi la parte
positiva dell’onda quadra è controbilanciata da una parte negativa della
stessa dimensione. Se si cambia il rapporto fra la parte positiva e quella
negativa si genera un cambiamento della forma dell’onda che ha ripercus-
sioni sul timbro dell’onda stessa. Questo rapporto è chiamato duty cycle
e si misura in genere con un valore compreso fra 0 e 1. Un duty cycle di
0.5 rappresenta l’onda quadra mentre un duty cycle di 0.75 significa che la
parte positiva è in rapporto di 3:1 rispetto a quella negativa.

In figura 86 l’oggetto expr∼ è modificato rispetto a quello della figura


85. Se i valori superano il valore in entrata nell’inlet destro emetti segnale
1, altrimenti emetti segnale di -1. Questo implica che possiamo variare
il valore-soglia. Mentre prima il valore soglia era fissato a zero e quindi
l’onda risultava simmetrica, ora tale valore può essere cambiato: se aves-
simo ad esempio un valore soglia pari a 0.75 (75 nella number box) expr
trasformerebbe questo valore in 0.5 e il il costrutto if risulterebbe essere: se
il valore è maggiore di -0.5 emetti 1, altrimenti 0. Ne risulterebbe un’onda
rettangolare con porzione positiva più lunga di quella negativa.

91
duty cycle wave
frq (0 - 100)
200 75

osc~ 200

$1 40

line

expr ((1 - ($f1 / 100)) * 2) - 1

expr~ if (($v1 > $f2), 1, -1)

metro 100
dac~
tabwrite~ wave

Figure 86: duty cycle dell’onda quadra

Questa modificazione del duty cycle può essere gestita da un segnale, gen-
eralmente un LFO, un Low Frequency Oscillator, di cui parleremo più avanti.
Basti per ora sapere che un LFO è un normale oscillatore, specializzato nella
generazione di frequenze molto basse, al di sotto della banda audio (<
30 hz). Usare un segnale di controllo per modificare il duty cycle realizza
la cosiddetta Pulse Width Modulation, utilizzata in molti sintetizzatori ana-
logici negli anni ’70.
In figura 87 un oscillatore con frequenza 0.25 controlla il duty cycle dell’onda
quadra. L’ampiezza viene moltiplicata per 0.99 in modo che non raggiunga
mai 1, poiché con ampiezza 1 il segnale è tutto positivo, quindi non c’è
alternanza fra parte positiva e negativa del segnale. Di conseguenza ci
sarebbe assenza di oscillazione, e di suono.

8.2.3 ONDA A DENTE DI SEGA

L’onda a dente di sega ha un periodo costituito da un segmento che va


da -1 a 1. Si ottiene sommando tutte le armoniche, con ampiezza pari al
reciproco del numero d’ordine dell’armonico e moltiplicate per -1:

92
wave

frq
300

osc~ 200

osc~ 0.25

*~ 0.99

expr~ if (($v1 > $v2), 1, -1)

metro 100
dac~
tabwrite~ wave

Figure 87: variazione del duty cycle tramite un segnale di controllo

arm 1 arm 2 arm 3 arm 4 arm 5 arm 6 arm 7


-1 − 12 − 13 − 14 − 15 − 16 − 17

In figura 88 ci sono due forme d’onda a dente di sega ottenute l’una con il
comando sinesum l’altra con un algoritmo.

phasor∼

L’onda a dente di sega è utilizzata spessissimo come segnale di controllo.


In Pd c’è un oggetto che implemente un’onda a dente di sega nel campo

93
dentedisega dentedisega2

;
dentedisega sinesum 515 -1 -0.5 -0.33 -0.25 -0.2 -0.166666
-0.142857 -0.125 -0.111111 -0.1 -0.0909 -0.0833 -0.0769
-0.0714 -0.0666 -0.0625 -0.0588 -0.0555 -0.0526 -0.05
-0.0476 -0.0454 -0.0434 -0.0416;
dentedisega normalize 1

515

until

int 0 + 1

mod 515

expr (($f1 / 515) * 2) - 1

tabwrite dentedisega2

Figure 88: l’onda a dente di sega ottenuta in due modi diversi

positivo, ovvero con valori che si muovono linearmente da 0 a 1. Tale


oggetto è phasor∼, utile per moltissime applicazioni.
Uno degli usi di phasor∼ è quello di utilizzarlo come segnale da modifi-
care con l’oggetto expr∼ in modo molto versatile. Ad esempio è possibile
costruire una patch per la Pulse Width Modulation con un algoritmo più sem-
plice di quello presentato in 8.2.2. La patch si può osservare in figura 90.
Il ciclo if è leggermente diverso da quello precedente. La condizione deve
verificare semplicemente il rapporto fra il segnale di phasor∼ e quello di
osc∼.

8.2.4 ONDA TRIANGOLARE

Come per l’onda quadra, quella triangolare può essere generata con diversi
metodi. Qui riproponiamo gli stessi della sezione precedente:

94
saw
phasor~ 100

metro 120

tabwrite~ saw

Figure 89: l’onda a dente di sega come segnale di controllo, generata con phasor∼

osc~ 0.125
phasor~ 400
expr~ ($v1 * 0.49) + 0.5

expr~ if (($v1 > $v2), 1, -1)

dac~

Figure 90: l’onda a dente di sega come segnale di controllo, generata con phasor∼

- vettore e comando sinesum

- vettore disegnato da algoritmo

- intervento diretto sul segnale

Nel primo caso dobbiamo usare le armoniche dispari con ampiezza inversa
rispetto al quadrato del numero d’ordine dell’armonico e poi moltiplicare
le ampiezze alternativamente per 1 e -1

arm 1 arm 2 arm 3 arm 4 arm 5 arm 6 arm 7


1 0 − 312 0 1
52
0 − 712

Nel secondo caso dobbiamo disegnare il grafico del vettore costruendo


tre segmenti attraverso un algoritmo, il primo segmento va da 0 a 1, il

95
secondo da 1 a -1, il terzo da -1 a 0. In figura 91 ci sono le due forme
d’onda, la prima approssimata con il comando sinesum (somma dei primi
19 armonici), la seconda perfetta. Nella figura successiva (92) è mostrato
l’algoritmo per disegnarla.
triang triang2

;
triang sinesum 515 1 0 -0.111111 0 0.04 0 -0.020408 0
0.012345 0 -0.008264 0 0.005917 0 -0.044444 0 0.00346 0
-0.00277;
triang normalize 1

pd triang2

Figure 91: nel grafico triang l’onda triangolare è approssimata con la somma di
19 armonici, mentre in triang2 l’onda è disegnata in modo perfetto

Per l’intervento diretto sul segnale si può utilizzare un oggetto phasor∼


filtrato da un oggetto expr∼ con un ciclo if a cui dire: se il segnale è
minore di 0.5 scrive ina retta da 0 a 1, altrimenti scrivi una retta da 1 a 0,
poi moltiplica per 2 e sottrai uno per riscalare il tutto fra -1 e 1.
Anche nel caso dell’onda triangolare esiste il duty cycle che determina la
posizione del vertice alto del triangolo. Un duty cycle di 0.5 è un’onda
triangolare isoscele mentre con un duty cycle ad esempio di 0.75 il vertice
alto del triangolo è spostato verso destra (fig. 94).

96
loadbang

131

256 until

until int 384 + 1

128 int 128 + 1 mod 131

until mod 256 + 384

int 0 + 1 + 128 t f f

mod 128 t f f expr (-1 - (($f1 - 384) / -128))

t f f expr (1 - (($f1 - 128) / 128))

expr ($f1 / 128)

tabwrite triang2

Figure 92: l’algoritmo per produrre una forma d’onda triangolare, in una tabella
di 512 + 3 punti

phasor~ 200

expr~ if (($v1 < 0.5), (($v1 * 2) * 2) - 1, (1 - (($v1 *


2)-1)) * 2 - 1)
tri

metro 100

dac~ tabwrite~ tri

Figure 93

97
phasor~ 250 dutycycle

0.367
expr~ if ($v1 <= $f2, $v1 * (1 / $f2), (1 - $v1) * (1 /
(1-$f2))) * 2 - 1
tri

metro 100

dac~ tabwrite~ tri

Figure 94

98
9 I L PA N N I N G

9.1 L’ OGGETTO dac∼

Negli esempi proposti fino ad ora abbiamo sempre inviato il segnale in


uscita all’oggetto dac∼ che ha il compito di convertire il segnale digitale in
analogico, in modo da poterlo ascoltare. Come si può osservare l’oggetto
suddetto ha due inlet. In effetti abbiamo sempre inviato il segnale smistan-
dolo in entrambi gli inlet. dac∼ infatti consente di inviare il suono verso
due canali, uno sinistro e uno destro. Fino ad ora abbiamo sempre inviato
il segnale verso entrambi i canali ottenendo come risultato che il suono
sia identico in entrambi, ma potremmo decidere di inviare il segnale verso
uno solo dei due.

1 2

osc~ 120 osc~ 120

*~ 0.25

dac~ dac~

Figure 95: in (1) il segnale dell’oscillatore è inviato al solo canale sinistro, in (2) il
segnale viene inviato con massima ampiezza al canale sinistro, mentre
con ampiezza ridotta del 75% al canale destro

In figura 95(1) il segnale viene inviato solo al canale sinistro, mentre in (2)
il segnale avrà un peso maggiore sul canale sinistro poiché prima di essere
collegato al canale destro viene ridotto in ampiezza.

99
9.2 C ONTROLLO DEL panning

Nella prossima patch realizziamo un semplice algoritmo per controllare la


posizione del suono nel campo stereofonico.

sx dx

expr ($f1 / 100)

0.346

osc~ 440
expr sqrt($f1 / 100)

expr sqrt(1 - ($f1 / 100))

0.808 0.588

$1 20 $1 20

line~ line~

*~ *~

dac~

Figure 96

In figura 96 è mostrato l’algoritmo di Pd. Attraverso una slider orizzontale


possiamo posizionare il suono nel campo stereo, se l’indicatore si trova al
centro avremo un suono posizionato esattamente a metà fra i due canali,
in alternativa possiamo posizionare il suono verso destra o verso sinistra
spostando l’indicatore.
La slider è impostata in modo da agire in un range compreso fra 0 e 100, il
valore in uscita viene diviso per 100 in modo da produrre un range com-

100
preso fra 0.0 e 1.0. Nel caso del canale destro questo valore decimale viene
collegato con il moltiplicatore per il canale destro impostando l’ampiezza
del segnale lo stesso canale. Per il canale sinistro invece il valore viene
sottratto da 1.0 in modo da essere il complementare dell’altro. E’ neces-
sario inoltre calcolare la radice quadrata dei due valori, poiché l’intensità
del suono percepito è proporzionale al quadrato dell’ampiezza del seg-
nale stesso. Entrambi i dati in uscita vengono infine passati per l’oggetto
line∼ che rende più graduale il passaggio da un valore all’altro elimi-
nando l’eventuale effetto a scalini che si produrrebbe.
Invece di controllare direttamente la spazializzazione del segnale tramite
un oggetto grafico, possiamo ultilizzare un oscillatore a basse frequenze
(LFO) per far muovere il suono fra i due canali in uscita.

osc~ 120 osc~ 1

expr~ ($v1 * 0.5) + 0.5

expr~ sqrt(1 - $v1)

expr~ sqrt($v1)

*~ *~

dac~

Figure 97

Nella figura 97 è mostrata questa situazione: il segnale dell’oscillatore di


destra viene reso unipolare (vedi paragrafo successivo) producendo così
un’onda con ampiezza compresa fra 0 e 1. Subendo le stesse operazioni
della figura precedente (fig. 96) produce un’oscillazione del segnale fra
il canale sinistro e il canale destro. Analogamente possiamo controllare il
panning attraverso un’onda quadra che alterni valori di 0 e 1 (fig. 98)

101
osc~ 120 osc~ 1

expr~ if($v1 < 0.5, 1, 0)

expr~ sqrt(1 - $v1)

expr~ sqrt($v1)

*~ *~

dac~

Figure 98

9.2.1 S EGNALI BIPOLARI E UNIPOLARI

Nella patch in figura 97 abbiamo usato un particolare tipo di segnale, detto


unipolare. Fino ad ora tutti i segnali che abbiamo incontrato erano bipolari,
perché la loro forma d’onda oscilla fra i valori positivi e i valori negativi.
Per realizzare algoritmi in cui ci sono segnali che controllano altri segnali,
come nel caso del panning o del tremolo è necessario avere a disposizione
dei segnali unipolari, ovvero segnali con valori che oscillano solo fra i valori
positivi (fig. 99).

9.2.2 IL DC OFFSET

Per ottenere un’onda unipolare é necessario operare una variazione su


un’onda bipolare. Questa variazione si realizza aggiungendo al segnale
bipolare un valore costante detto DC offset. Se ad una sinusoide che oscilla
fra -1 e 1 si aggiunge il valore costante 1, si otterrà una nuova sinusoide
oscillante fra 0 e 2, questo perché la distanza fra l’ampiezza massima e
quella minima della sinusoide equivale a e (1-(-1) = 2). In figura 129 si
può osservare che la distanza del segnale unipolare, che oscilla fra 0 e 1,
equivale alla metà di quello bipolare, che oscilla fra -1 e 1. Quindi oltre
all’aggiunta della costante, é necessario dividere il segnale per 2 o, meglio,
moltiplicarlo per 0.5 (le moltiplicazioni per il calcolatore sono più veloci
delle divisioni). Ricapitolando:

102
Segnale bipolare e unipolare

a)

b)

Figure 99: L’ampiezza del segnale (a) oscilla fra valori positivi e negativi, mentre
(b) è polarizzato nel campo positivo

(sig[−1,1] ∗ 0.5) + 0.5 = sig[−0.5,0.5] + 0.5 = sig[0,1]

Nella patch di Pd in figura 130 é mostrato un segnale bipolare trasformato


in un segnale unipolare tramite l’oggetto expr∼.

103
1.0

1.0

0.5

0.5
a)
0.0

0.0


−0.5

−0.5
−1.0

−1.0

1.0

1.0

0.5

0.5
b)
0.0

0.0

−0.5

−0.5
−1.0

−1.0

Figure 100: la distanza massima fra l’ampiezza positiva e quella negativa del seg-
nale bipolare (a) é doppia rispetto a quella del segnale (b)

104
osc~ 200 bipolare

metro 100

tabwrite~ bipolare

expr~ ($v1 * 0.5) + 0.5

unipolare
tabwrite~ unipolare

dac~

Figure 101: l’oggetto expr∼ permette facilmente di effettuare le due operazioni


sul segnale per trasformarlo trasformano da bipolare a unipolare

105
10 SINTESI ADDITIVA E SINTESI
VETTORIALE

10.1 S INTESI ADDITIVA

Definizione: Date n onde, si ha sintesi additiva quando si sommano tali


onde.
Risultato: La somma di onde sinusoidali produce suoni complessi es-
tremamente eterogenei.

Concettualmente la sintesi additiva è una tecnica semplice, ma può essere


molto costosa in termini di consumo di CPU e difficile da controllare e
gestire

10.1.1 SINTESI ADDITIVA A SPETTRO ARMONICO

La sintesi additiva a spettro armonico è costituita da sinusoidi che sono in


rapporto frequenziale armonico, cioè ognuna multipla dell’altra.

Il sistema più semplice per implementare questo genere di sintesi in Pd è


quello di utilizzare una tabella in cui disegnare la forma d’onda risultante
dalla somma delle sinusoidi e l’oggetto tabosc4∼ per leggere il contenuto
della tabella. È quello che abbiamo già visto in occasione della descrizione
delle varie forme d’onda e di come costruirle. Quella è una forma di sintesi
additiva, quindi non ci soffermeremo troppo a lungo su questo passaggio.
Rimandiamo alla patch in fig. 102.

10.1.2 SINTESI ADDITIVA A SPETTRO NON ARMONICO

La sintesi additiva a spettro non armonico non può fare uso delle tabelle
poiché le sinusoidi che compongono la forma d’onda non sono in rapporto
armonico fra loro una tabella comune non consentirebbe ai vari periodi
delle onde di essere completi.

106
Frequenza waveform
0

tabosc4~ waveform

dac~

;
waveform sinesum 512 1 0.5 0.25 0.125 0.0625 0.03125
0.015625 0.078125;
waveform normalize 1

Figure 102: Una patch per la sintesi additiva a spettro armonico

È necessario quindi implementare questa forma di sintesi additiva con tanti


oscillatori quante sono le sinusoidi che si vogliono utilizzare. Ogni oscilla-
tore avrà la sua frequenza e la sua ampiezza. Nella patch in fig. 103 ci sono
8 oscillatori con la propria frequenza (in alto a sinistra) e una subpatch per
controllare l’ampiezza.

10.2 S INTESI VETTORIALE

Gli esempi di sintesi additiva che abbiamo esaminato in precedenza hanno


il limite di produrre spettri costanti, invariabili nel tempo. Questo pro-
duce timbri fissi, quindi freddi e astratti. Ci sono molti modi per cambiare
il timbro nel tempo: variare la frequenza di alcune sinusoidi nella sin-
tesi a spettro inarmonico ad esempio, oppure cambiare l’ampiezza delle
parziali. Uno dei sistemi usati per cambiare dinamicamente il timbro di
una forma d’onda è stato introdotto nel 1986 con la produzione del sinte-
tizzatore Prophet VS. L’idea è quella di avere a disposizione delle forme
d’onda fisse e di un dispositivo che permetta di passare da una all’altra
tramite crossfading dell’ampiezza. In sostanza le onde vengono sommate,
ma l’energia delle onde nella somma non è costante, all’aumentare di
un’ampiezza diminuisce l’altra e viceversa. Questa tecnica, detta sintesi
vettoriale consente quindi di avere un dispendio di CPU molto basso per-
ché le tabelle sono fisse. Si tratta semplicemente do organizzare l’algoritmo

107
pd ampiezze

80 712
150 890
320 1780
500 2615

osc~ osc~ osc~ osc~ osc~ osc~ osc~ osc~

*~ *~ *~ *~ *~ *~ *~ *~

(0-1000)

/ 1000 wf
*~
$1 20

line~

dac~ tabwrite~ wf

Figure 103: una patch per la sintesi additiva a spettro non armonico

in modo che esegua il passaggio da un’ampiezza all’altra in modo che la


somma rimanga costante. In figura 104 abbiamo implementato un sem-
plice crossfading fra due entità che si muovono nel range di zero e uno.
All’aumentare di una diminuisce l’altra. L’algoritmo non ha bisogno di
grandi spiegazioni. L’oggetto swap consente di invertire la posizione dei

108
due valori che entrano dagli inlet, ma, come in questo caso, se swap ha un
argomento, lo stesso sarà mandato fuori dall’outlet di sinistra consentendoci
di sottrarre da questo il valore dell’outlet di destra.

A________________B

swap 1

0.242 0.757

Figure 104: Implementazione del crossfading

10.2.1 DISSOLVENZA INCROCIATA FRA DUE TABELLE

Nella patch di questa sezione mostriamo un algoritmo per la dissolvenza in-


crociata (traduzione italiana di crossfading) fra due tabelle contenenti forme
d’onda semi-casuali. prima esaminiamo l’abstraction che genera tali onde
(fig. 105
Grazie al contatore viene disegnata nella tabella, il cui nome è dato dal
primo argomento passato all’oggetto randomwave, un’onda sunosoidale ad
ogni punto della quale è aggiunto un valore casuale determinato dal sec-
ondo argomento passato all’oggetto. Ad esempio se tale valore è impostato
a 0.5, i valori random prodotti saranno compresi fra -0.25 e +0.25.

La patch della figura successiva (106) invece mostra l’algoritmo per la dis-
solvenza vera e propria. L’algoritmo non necessita di spiegazioni partico-
lari. La parte in altro a destra mostra la parte che si occupa del crossfading
mentre in basso c’è uno slider per impostare l’ampiezza dell’onda risul-
tante.

109
Generatore di onde casuali

loadbang

512 table $1 515

t b f

0 until

t b b

randomF $2 expr $2 * 0.5

normalize 1 float 0 + 1
expr ($f1 - $f2) 1
send $1

expr (sin(($f1 / 512) * 6.283185305)) + $f2

tabwrite $1

Figure 105: L’abstraction randomwave

10.2.2 DISSOLVENZA INCROCIATA FRA QUATTRO TABELLE

Il Prophet VS implementava una sintesi vettoriale che gestiva quattro forme


d’onda contemporaneamente. In Pd esiste un oggetto che ci consente di
fare la stessa cosa. Si tratta dell’oggetto grid che si presenta come un
quadrato all’interno del quale si può muovere un cursore che ci permet-
tere di gestire praticamente due slider contemporaneamente. Muovendo il
cursore da sinistra a destra si modificherà un valore, muovendosi dall’alto
verso il basso si modificherà l’altro.

La patch in figura 107 mostra l’implementazione della sintesi vettoriale


con quattro tabelle generate da randomwave. In alto a sinistra l’oggetto
grid gestisce le ampiezze delle quattro forme d’onda. L’asse orizzontale
gestisce le prime due (wave1 e wave2) mentre l’asse verticale le altre due.
La subpatch pd grid eval (fig. 108) si occupa di fare gli opportuni calcoli per
attribuire i valori ai quattro moltiplicatori di ampiezza.

110
A________________B
randomwave wf1 2
randomwave wf2 1.5

swap 1

1 0
8000

pack 0 15 pack 0 15

tabosc4~ wf1 tabosc4~ wf2 line~ line~

*~ *~

Amp
+~

*~
pack 0 15

dac~ line~

Figure 106: Dissolvenza incrociata fra due tabelle

111
r grid

loadbang

color 200 200 200

send grid

Frequenza
60
pd grid_eval

tabosc4~ wave1 tabosc4~ wave2 tabosc4~ wave3 tabosc4~ wave4

*~ *~ *~

*~
+~

+~ randomwave wave1 0.5


randomwave wave2 0.25
randomwave wave3 0.74
+~
randomwave wave4 1.75

dac~

Figure 107: Dissolvenza incrociata fra quattro tabelle

112
inlet inlet

/ 100 / 100

expr (1 - $f1) expr (1 - $f1)

* * *
*

$1 25 $1 25 $1 25 $1 25

line~ line~ line~ line~

outlet~ outlet~ outlet~ outlet~

Figure 108: La subpatch che distribuisce le ampiezze fra i quattro segnali

113
11 S I N T E S I S OT T R AT T I VA

11.1 L A SINTESI SOTTRATTIVA

A differenza della sintesi additiva, che realizza la somma di sinusoidi per


ottenere spettri complessi, la sintesi sottrattiva insiste su spettri molto com-
plessi per ottenere suoni più semplici. Per sottrarre frequenze da un suono
complesso si usano dei dispositivi software detti filtri, che si applicano su
suoni che hanno uno spettro estremamente ricco, come i rumori. Schematiz-
zando, il suono sorgente prima di essere inviato all’uscita passa attraverso
un filtro, che realizza certe condizioni richieste (fig. 109).

segnale in entrata

filtro

segnale in uscita

Figure 109: schema di un filtraggio di segnale semplice

11.1.1 IL RUMORE

In generale si intende per rumore un suono non desiderato che disturba


la percezione di un’informazione sonora. In musica elettronica un rumore
è una sequenza di oscillazioni casuali. Si distinguono vari tipi di rumori.
Il rumore bianco è quello costituito da frequenza uniformemente distribuite,

114
prodotte alla velocità della frequenza di campionamento. In altre parole,
se ci si opera alla frequenza di campionamento di 44100 hertz, il rumore
bianco è costituito da frequenze casuali (con ampiezza casuale) emesse
1
ogni 44100 di secondo. Lo spettro del rumore bianco si presenta come in
figura 110: le frequenze occupano tutta la banda audio.

Rumore bianco

0 2000 4000 6000 8000 10000 12000 14000 16000 18000 20000

Figure 110: spettro del rumore bianco

Il rumore rosa ha una distribuzione spettrale diversa dal precedente: via via
che le frequenza sono più alte l’ampiezza media del segnale si abbassa, per
la precisione si abbassa di 3 db ogni ottava (fig. 111).

Rumore rosa

0 2000 4000 6000 8000 10000 12000 14000 16000 18000 20000

Figure 111: spettro del rumore rosa

115
In Pd questi due tipi di rumore sono implementati rispettivamente dagli
oggetti noise∼ e pink∼ che non accettano nessun tipo di argomento. L’oggetto
rand∼ invece genera un rumore limitato in banda, questo significa che il
generatore produce una banda di rumore che va da 0 alla frequenza im-
postata, successivamente produce delle bande secondarie larghe quanto la
frequenza impostata ma di ampiezza sempre minore. L’esempio in figura
(112) mostra lo spettro prodotto da rand∼ con frequenza 2500 hz.

Rumore band limited

0 2000 4000 6000 8000 10000 12000 14000 16000 18000 20000

Figure 112: spettro di rumore band-limited con frequenza di 2500 hz

Nella patch in figura 113 l’oggetto polygate∼ consente di scegliere quale


generatore inviare a dac∼. Accetta come argomento il numero dei segnali
in entrata e il tempo con cui passare da uno all’altro. Il messaggio choice
consente di effettuare la scelta.

I rumori con il loro spettro ricchissimo sono ideali per poter essere filtrati
e costituiscono i segnali sorgenti privilegiati per la sintesi sottrattiva.

11.2 I FILTRI

Molto genericamente un filtro digitale è un algoritmo attraverso il quale un


segnale viene trasformato in un altro segnale. Meno genericamente un fil-
tro è un dispositivo software che attenua o intensifica alcune regioni di uno
spettro.

116
2500
0

choice $1 noise~ pink~ rand~

polygate~ 3 100

dac~

Figure 113: selezione del tipo di rumore tramite l’oggetto polygate∼

Tali filtri possono essere implementati secondo i due schemi mostrati in


figura 114.

(a)
delay

Input + Output

(b)
delay

Input + Output

Figure 114: I due più comuni schemi di implementazione per i filtri digitali

Nell’immagine (a) una copia del segnale viene ritardata nell’ordine di


pochi campioni e sommata al campione in entrata. Tale modalità di im-

117
plementazione descrive i filtri a risposta finita all’impulso (Finite Impulse
response, FIR) perché il segnale elaborato è solo quello in entrata. In (b)
una copia del segnale in uscita viene ritardato e combinato con il segnale
in entrata, in questo caso si parla di un filtro a risposta infinita all’impulso
(Infinite Impulse Response, o IIR), poiché il segnale in uscita rientra nel filtro
per essere rielaborato. Per tale ragione si parla in questo caso anche di
Filtri Ricorsivi.

La somma (o la sottrazione) di tali campioni produce una forma d’onda di-


versa dall’originale e quindi un nuovo spettro. L’aggiunta (o la sottrazione)
di più campioni ritardati può produrre una grande varietà di filtri. Tale
relazione fre segnale in entrata e segnale in uscita è descitta attraverso
un’equazione. Il segnale in uscita è il risultato di somme, sottrazioni e
moltiplicazioni fra il campione attuale e campioni ritardati. Questo tipo di
equazione è detta equazione alla differenza lineare.

La figura 115 mostra lo schema di un semplice filtro mediano passa-basso.


Si dice mediano perché fa la media fra il campione attuale e il campione
precedente, cioè somma i due campioni e poi divide per due. Il risultato è
un filtro passa-basso perché attenua le alte frequenze.

0.5
delay
*
0.5
Input
* + Output

Figure 115: Filtro di media passa-basso

L’equazione di questo filtro è la seguente:

y[n] = (0.5 ∗ x [n]) + (0.5 ∗ x [n − 1])

dove x è il segnale in entrata, y il segnale in uscita, n il numero del campi-


one e 0.5 il coefficiente del filtro.

In pd tramite l’oggetto z∼ è possibile ritardare un segnale nell’ordine di


singoli campioni. In figura 116 è mostrata l’implementazione del filtro ap-

118
pena descritto.

noise~
z~ 1

*~ 0.5

*~ 0.5
+~

dac~

Figure 116: Filtro di media passa-basso in pd

z∼ prende come argomento il numero dei campioni da ritardare, nel nos-


tro caso 1. Tale filtro tende a smussare le spigolature del segnale, che sono
improvvise e rapidissime, per tale motivo generano frequenze alte. Precisa-
mente il filtro attenua le frequenze fino alla metà della frequenza di campi-
onamento (tipicamente 22050). L’immagine in figura 117 mostra la curva
descritta dal filtro nel dominio della frequenza. Tale rappresentazione de-
scrive la risposta in frequenza del filtro.

1
amp

0
freq 22050

Figure 117: Risposta in frequenza del filtro di media passa-basso

Se invece si sommare i due campioni, si sottraggono, si otterà un filtrag-


gio delle basse frequenze, l’esatta inversione del precedente. Tale filtro è
detto passa-alto poiché lascia passare le alte frequenze fino alla metà della

119
frequenza di camipnamento. L’equazione diventa quindi:

y[n] = (0.5 ∗ x [n]) − (0.5 ∗ x [n − 1])

e la risposta in frequenza di tale operazione è mostrata in figura 118.

1
amp

0
freq 22050

Figure 118: Risposta in frequenza del filtro di media passa-alto

Il numero dei campioniritardati determina anche l’ordine del filtro. Un


filtro del primo ordine sarà implementato con un unico campione ritardato,
secondo questa equazione generica:

y[n] = ( a0 ∗ x [n]) ± ( a1 ∗ x [n − 1])

dove a0 e a1 sono, rispettivamente, il coefficienti del campione originale


e del campione ritardato. Aumentando i campioni e quindi i coefficienti,
aumenta anche l’ordine del filtro. Come vedremo, l’ordine del filtro deter-
mina anche la sua risposta in frequenza.

Un filtro del secondo ordine avrà la seguente equazione:

y[n] = ( a0 ∗ x [n]) ± ( a1 ∗ x [n − 1]) ± ( a2 ∗ x [n − 2])

Come abbiamo visto tali filtri sono detti FIR, perché non creano ricorsioni
fra il segnale di entrata e il segnale di uscita e fino al secondo ordine sono

120
molto stabili, infatti per creare filtri di ordine superiore si è solito usare
filtri del primo e del secondo ordine in scascata piuttosto che implementare
un unico filtro di ordine superiore.

I filtri IIR invece sommano il segnale in entrata con i campioni ritardati


rientranti nel sistema. L’equazione generale per un filtro IIR del primo or-
dine è la seguente:

y[n] = ( a0 ∗ x [n]) ± ( a1 ∗ x [n − 1]) ± (b1 ∗ y[n − 1])

dove b1 è il coefficiente del campione ritardato. b0 ovviamente non è pre-


sente perché sarebbe il coefficiente del campione originale in entrata, già
presente.

Un’altro modo per rappresentara il comportamento di un filtro è quello


denominato risposta all’impulso (Impulse Response) che viene realizzato nel
dominio del tempo. Per rappresentare tale comportamento si una un im-
pulso, cioè il segnale più breve che un sistema digitale possa realizzare:
un singolo campione. Infine esiste un terzo modo, la risposta in fase, che
descrive lo spostamento della fase delle sinusoidi componenti del suono
filtrato.

Non ci addentreremo oltre nella descrizione tecnica dei filtri digitali, che
esulerebbe dagli scopi di questo testo, ma diremo che attualmente i filtri
più usati sono raggrupabili in 4 tipi:

• passa-basso

• passa-alto

• passa-banda

• escludi-banda

11.3 I PARAMETRI DEI FILTRI

I filtri passa-basso e passa-alto devono avere almeno un parametro per


poter funzionare, cioè la frequenza di taglio (cutoff frequency). Nel primo

121
caso tale quantità indica la frequenza al di sopra della quale vengono atten-
uate le altre frequenze, nel secondo, al contrario, indica la frequenza sotto
la quale inizia l’attenuazione.

Per essere precisi la frequenza di taglio è, convenzionalmente, il punto in


cui il filtro riduce il segnale allo 0.707 del suo massimo valore, il che, con
apiezza pari a 1, corrisponde a una riduzione di 3 decibel. Per questo a
volte la frequenza di cutoff viene definita 3dB point.

Le frequenze attenuate al di sopra (o al di sotto nel caso di un passa-alto)


della frequenza di cutoff costituiscono la banda bloccata del filtro stopband, le
frequenze passanti costituiscono invece la banda passante (passband).

Gli altri due filtri (passa-banda e escludi-banda) sono una derivazione dei
primi. infatti se si filtra un segnale con una coppia passa-basso/passa-alto
si realizzarà un filtro passa-banda o escludi-banda. L’immagine 119 mostra
questa situazione. Nella figura in alto la zona quadrettata rappresenta la
regione dello non filtrata, in quella in basso la zona quadrettata in alto rap-
presenta la zona eliminata dallo spettro.

I valori necessari per tali filtri sono due frequenze di cutoff, una per il passa-
basso, l’altra per il passa-alto.

I filtri passa-banda (ed escludi-banda, che è il suo inverso) sono comunque


ormai algoritmi indipendenti dagli altri filtri e usano parametri diversi
per funzionare. Il primo valore è sempre una freuqneza centrale (center fre-
quency) e una larghezza di banda bandwidth, che corrisponde alla frequenza
di taglio superiore meno quella inferiore. Tale valore è spesso sostituito
dal fattore Q, che corrisponde al rapporto fra la frequenza centrale e la
larghezza di banda:

fc
Q= B

Ovviamente vale anche l’operazione opposta, per sapere qual’è la larghezza


di banda partendo da Q, si avrà:

fc
B= Q

122
bandpass filter

s
as

lo w
hp

pa
h ig

ss
bandreject filter

ss lo w
h pa pa
h ig ss

Figure 119: Filtro passa-banda e filtro escludi-banda creati a partire da un filtro


passa-basso e uno passa-alto

La larghezza di banda è quindi inversamente proporzionale al fattore Q.

Ma quanto è efficace un filtro? In altre parole, di quanto attenua le fre-


quenze? Naturalmente dipende dal filtro, e in base alla capacità di atten-
uazione i filtri vengono classificati secondo ordini che definiscono il livello
di attenuazione in dB per ottava, cioè a ogni raddoppio della frequenza.
Un filtro del primo ordine attenua di 6dB per ottava le frequenze, uno del
secondo ordine le attenua di 12 dB, e così via. questo significa ad esempio
che in presenza di un filtro passa-basso del primo ordine con frequenza di
taglio di 200 hertz. L’ampiezza a 400 hertz sarà ridotta di 6 db, a 800 hertz
ci sarà una riduzione di 12 dB, a 1600 hertz di 18 db e così via. La figura
120 mostra la risposta in frequenza di due filtri di primo e secondo ordine.
Naturalmente l’ordine di un filtro può riguardare i filtri passa-basso e
passa-alto, ma non i passa-banda e gli escludi-banda che aumentano o
diminuiscono la loro capacità di attenuazione in base alla bandwidth definita.
La figura 121 mostra il comportamento di un filtro passa-banda al variare
del fattore Q.

123
I ord.

-6 dB

II ord.

-12 dB

x 2x 4x

Figure 120: Curva della risposta in frequenza di filtri del primo e secondo ordine,
x è la frequenza di cutoff

-3 db

Q=2

Q=8

Fc

Figure 121: Comportamento di un filtro passa-banda in relazione al fattore Q

11.4 I FILTRI IN PD

Pd possiede una vasta collezione di filtri, la maggior parte dei quali in-
trodotti da librerie esterne nella versione extended. Per brevità analizzer-
emo l’uso di alcuni oggetti della versione nativa.

I due oggetti lop∼ e hip∼ implementano rispettivamente un filtro passa-


basso e uno passa-alto del primo ordine, mentre bp∼ e vcf∼ sono dei
passabanda. I primi due accettano come unico argomento la frequenza di
cutoff, mentre gli altri la frequenza centrale e il fattore Q. Con questi oggetti
è anche possibile realizzare un filtro escludi-banda, sia usando una coppia
di passa-basso/passa-alto che usando un passabanda (basta sottrarre il seg-

124
nale del passabanda dal segnale originale).

La figura 122 mostra lop∼, hip∼ e bp∼ in azione sulla stessa sorgente.
L’oggetto polygate∼ permette di lasciar passare il segnale indicato dal
messaggio choice seguito dal numero dell’inlet scelto. Un messaggio pari a
zero chiude l’uscita per qualunque segnale. I due argomenti dell’oggetto
sono il numero degli inlet e il tempo in millisecondi in cui avviene la tran-
sizione fra un segnale e l’altro.

off
lp noise~
hp
bp lop~ 40 194 bp_cutoff
hip~ 10000
choice $1 bp~ 200 10
polygate~ 3 80

sig~

lop~ 5
*~

dac~

Figure 122: I filtri semplici di pd in azione

11.5 I L FILTRO vcf∼

Il filtro vcf∼ è uguale a bp∼ eccetto per il fatto di poter controllare il cutoff
via segnale. Questo consente dei realizzare dei controlli della frequenza di
taglio molto dinamici.

Nella patch in figura 123 un phasor∼ controlla il cutoff di un vcf∼ che filtra
il segnale di un altro phasor∼.
Il phasor∼ di destra crea 2 volte al secondo una rampa che viene molti-
plicata per 720 e sommata a 80, quindi va da 80 a 800. Questo rampa
va nell’inlet del cutoff del vcf∼. L’argomento dell’oggetto è il fattore Q,
che nella patch può essere variato attraverso la number box. La frequenza
principale del suono sorgente è generata da un altro phasor∼ a frequenza

125
phasor~ 80 phasor~ 2

8 *~ 720

+~ 80
vcf~ 5

sig~

lop~ 5
*~

dac~

Figure 123: Un filtro vcf∼ con controllo del cutoff attraverso un phasor∼

costante.

Nella patch c’è una particolarità: lo slider (con valori da 0 a 1) invia at-
traverso sig∼ il segnale che controllerà l’ampiezza a un filtro passa-basso
con frequenza 5. lop∼ smusserà le spigolature del segnale consentendo
il passaggio da un valore all’altro in modo graduale. Diminuendo la fre-
quenza del filtro l’interpolazione sarà più lenta, al contrario, sarà più rap-
ida all’aumentare della stessa.

11.6 U N sequencer CON vcf∼ E samphold∼

Nella prossima patch implementiamo un algoritmo che crea dei pattern, o


meglio, delle sequenze di note che vengono filtrate da un vcf∼. Si tratta di
una forma rudimentale di sequencer, cioè un dispositivo che emette segnali
di controllo per pilotare degli eventi sonori.

Gli oggetti principali della patch li conosciamo quasi tutti, un phasor∼ per
la lettura delle tabelle e il timing del sequencer, un vcf∼ per filtrare via
segnale la sorgente sonora e infine samphold∼, oggetto utilissimo per nu-
merose implementazioni.

126
samphold∼ è la forma contratta di sample and hold, campiona e trattieni ed
è, a modo suo, una forma di filtro. Generalmente un algoritmo sample and
hold prevede due parametri: un segnale da campionare e un segnale per
scandire il campionamento secondo certi criteri. Nel caso di samphold∼,
l’inlet di sinistra è deputato ad accettare il segnale che verrà campionato,
mentre quello di destra accetta il segnale di trigger. Ma come e quando
avviene il campionamento del segnale? esattamente quando il segnale di
destra passa da un valore non-zero a zero. Tipicamente si usa un phasor∼:
ogni volta che termina la rampa arrivando a uno, torna a zero, innescando
il processo di campionamento. Il segnale da campionare può essere invece
di qualunque tipo.

In figura 124 samphold∼ campiona 4 volte al secondo il segnale inviato da


noise∼, tale segnale viene, in uscita, costrotto nel range [0,1], poi molti-
plicato per 800 e sommato a 100, generando così valori casuali compresi
fra 100 e 900, che vanno a cambiare la frequenza di un oscillatore. La sub-
patch per l’ampiezza è solo un’incapsulamento di uno slider con un oggetto
lop∼, come abbiamo visto prima.

noise~ phasor~ 4

samphold~

abs~

*~ 800
interp_time
+~ 100
5
osc~

*~

dac~

Figure 124: La frequenza di un oscillatore controllata da samphold∼

127
12 MOULAZIONE AD ANELLO (RM),
T R E M O LO, M O D U L A Z I O N E
D ’A M P I E Z Z A ( A M )

12.1 L A MODULAZIONE AD ANELLO

Definizione: Dati due segnali, si ha la modulazione ad anello (Ring Modu-


lation, RM) quando si moltiplicano l’uno per l’altro nel dominio dell’ampiezza:

RM = sigα ∗ sigβ

Risultato: La RM produce un suono complesso, formato da tutte le fre-


quenze ottenute dalla somma e dalla differenza dei due segnali. Nel caso
più semplice, con due sinusoidi, avremo quindi:

RM = (α f + β f ), (α f − β f )

In termini matematici, la seconda regola di Werner esprime proprio questa


identità:

1
cos(α) ∗ cos( β) = [cos(α + β) + cos(α − β)] (1)
2
Quando i due segnali sono suoni complessi, il risultato della modulazione
ad anello sarà l’insieme delle somme e differenze fra tutte le frequenze
dei due suoni. Nella patch in figura 127 si ha una doppia modulazione
ad anello, con le sinusoidi di frequenza 2000, 500 e 650 hertz. Il risultato
della prima RM da frequenze di 2500 e 1500 hertz che vengono modulati
con la terza sinusoide (650 hz), producendo un suono finale formato dalla
somma di 4 onde: 3150, 1850, 2150, 850 hertz (vedi lo spettro in figura 128.
Schematizzando:
Dati i segnali α(2000hz), β(500hz), γ(650hz), si applica la modulazione ad
anello ai primi due e il risultato si ring-modula con il terzo:

- RM1 = (α f + β f ), (α f − β f )

128
Modulazione ad anello

0 1000 2000 3000

Figure 125: lo spettro risultante di una modulazione ad anello. Le frequenze delle


sinusoidi sono di 2000 Hz e 500 hz. Il risultato è un suono composto
da frequenze di 2500 hz e 1500 hz

osc~ 2000 osc~ 500

*~

dac~

Figure 126: la patch di Pd che implementa la Modulazione ad anello dello spettro


in figura 125

- RM1 = (2000 + 500), (2000 − 500)

- RM1 = 2500, 500

- RM2 = RM1 f ∗ γ f

129
- RM2 = RM1 f ∗ 650

- RM2 = (2500 + 650), (2500 − 650), (1500 + 650), (1500 − 650)

- RM2 = 3150, 1850, 2150, 850

osc~ 2000 osc~ 500

*~
osc~ 650

*~

dac~

Figure 127: doppia modulazione ad anello: 2 segnali vengono ring-modulati fra


loro e successivamente con un terzo

Storicamente la Modulazione ad anello è stata utilizzata per modificare il


timbro degli strumenti tradizionali. In quel caso un suono complesso viene
ring-modulato con un suono di sintesi, una sinusoide ad esempio. Tecnica-
mente non c’è alcuna differenza con la modulazione vista qui sopra, ma
si preferisce in queste circostanze parlare di suoni che vengono modifi-
cati con altri suoni: il suono da modulare viene definito Portante (Carrier),
mentre il segnale che modula è detto Modulante (Modulator).

12.2 S EGNALI BIPOLARI E UNIPOLARI

Per ottenere un’onda unipolare é necessario operare una variazione su


un’onda bipolare. Questa variazione si realizza aggiungendo al segnale
bipolare un valore costante detto DC offset. Se ad una sinusoide che oscilla
fra -1 e 1 si aggiunge il valore costante 1, si otterrà una nuova sinusoide

130
Modulazione ad anello doppia

0 1000 2000 3000 4000

Figure 128: lo spettro risultante dalla doppia modulazione ad anello

oscillante fra 0 e 2, questo perché la distanza fra l’ampiezza massima e


quella minima della sinusoide equivale a e (1-(-1) = 2). In figura 129 si
può osservare che la distanza del segnale unipolare, che oscilla fra 0 e 1,
equivale alla metà di quello bipolare, che oscilla fra -1 e 1. Quindi oltre
all’aggiunta della costante, é necessario dividere il segnale per 2 o, meglio,
moltiplicarlo per 0.5 (le moltiplicazioni per il calcolatore sono più veloci
delle divisioni). Ricapitolando:
(sig[−1,1] ∗ 0.5) + 0.5 = sig[−0.5,0.5] + 0.5 = sig[0,1]

Nella patch di Pd in figura 130 é mostrato un segnale bipolare trasformato


in un segnale unipolare tramite l’oggetto expr∼.

12.3 S EGNALE DI CONTROLLO DELL’ AMPIEZZA : IL TREMOLO

Definizione: Dato un segnale bipolare e uno sinusoidale unipolare, ha


luogo un tremolo quando il segnale unipolare, a basse frequenze, modula
l’ampiezza di quello bipolare.

Risultato: il tremolo non è altro che una variazione dell’ampiezza di un


segnale prodotta da un altro segnale. L’oscillatore che modula l’ampiezza
della Portante deve necessariamente emettere basse frequenze, per non

131
1.0

1.0

0.5

0.5
a) 0.0

0.0


−0.5

−0.5
−1.0

−1.0

1.0

1.0

0.5

0.5
b)
0.0

0.0

−0.5

−0.5
−1.0

−1.0
Figure 129: la distanza massima fra l’ampiezza positiva e quella negativa del seg-
nale bipolare (a) é doppia rispetto a quella del segnale (b)

interferire con la frequenza del suono modulato. Inoltre una frequenza


troppo alta non permetterebbe di percepire l’effetto tremolo desiderato.
Tradizionalmente esistevano degli oscillatori specializzati nella generazione
di basse frequenza, sotto i 30 hertz circa, utilizzati proprio come strumenti
di controllo di altri oscillatori. Gli LFO (Low Frequency Oscillator) in Pd
possono essere sostituiti dai normali oscillatori, che generano qualsivoglia
frequenza.
La patch in figura ?? realizza un tremolo semplice. Si può controllare inter-
attivamente la frequenza del tremolo con la number box in alto e l’ampiezza
del segnale in uscita con la slider orizzontale. Come si intuisce l’oscillatore
modulante determina la frequenza della variazione d’ampiezza, ma non
l’escursione dell’ampiezza stessa, che oscilla sempre fra 0 e 1. La figura

132
osc~ 200 bipolare

metro 100

tabwrite~ bipolare

expr~ ($v1 * 0.5) + 0.5

unipolare
tabwrite~ unipolare

dac~

Figure 130: l’oggetto expr∼ permette facilmente di effettuare le due operazioni


sul segnale per trasformarlo trasformano da bipolare a unipolare

132 mostra proprio questa situazione, il segnale (a) viene modulato in


ampiezza da (b) e il risultato (c) è un’oscillazione percepibile dell’ampiezza
fra 0 e 1.
Con la prossima patch un algoritmo più articolato del precedente realizza
un tremolo controllabile in frequenza, ma anche in ampiezza, in modo
da poter decidere anche l’escursione del tremolo. La figura 133 mostra
proprio questa situazione. L’onda (b) varia l’ampiezza producendo in (c)
un cambiamento graduale dell’entità del tremolo. In figura 134 la patch di
Pd che implementa l’algoritmo relativo. Le due number box consentono di
intervenire interattivamente sulla frequenza e sull’ampiezza del tremolo.
La frequenza agisce esattamente come in figura 131 mentre per l’ampiezza
il numero in entrata dalla number box di destra ha un range compreso fra
0 e 50 e in uscita viene diviso per 100, in modo da emettere un range fra
0 e 0.5. Il segnale viene moltiplicato per quel valore e il risultato viene
sommato al risultato di 1 meno il valore in entrata.

133
controllo_tremolo
osc~ 800
2

osc~ 1

expr~ ($v1 * 0.5) + 0.5

*~

$1 20

line~
*~

dac~

Figure 131: con la number box si può aumentare o diminuire la frequenza del
tremolo

Tremolo

a)

b)

c)

Figure 132: il segnale (a) viene moltiplicato per il segnale (b) generando il tremolo
rappresentato in (c)

134
Tremolo controllato in ampiezza

a)

b)

c)

Figure 133: il segnale (b) varia in ampiezza generando una variazione


dell’ampiezza di (c)

12.4 L A MODULAZIONE D ’ AMPIEZZA

Definizione: Dato un segnale bipolare, detto Portante, e uno unipolare,


detto Modulante, ha luogo una modulazione d’ampiezza (AM) quando il
segnale unipolare modula l’ampiezza di quello bipolare.

Risultato: La modulazione d’ampiezza produce un suono con uno spet-


tro in cui è presente la frequenza Portante e tutte le frequenza somma e dif-
ferenza fra Portante e Modulante. Tecnicamente la Modulazione d’ampiezza
è molto simile al tremolo, con la differenza che per il tremolo il segnale
Modulante è costituito da un segnale di frequenza molto bassa. Nell’AM
invece la frequenza Modulante è compresa nella banda audio. Dal punto
di vista trigonometrico abbiamo:

sin(α) ∗ (1 + sin( β)) = sin(α) ∗ sin( β) + sin(α) =


1
2 ( cos ( α − β ) − cos ( α + β )) + sin ( α )

135
osc~ 1600
frequenza
ampiezza
1
37
osc~ 1
/ 100

expr~ ($v1 * $f2) + (1 - $f2)

wave

*~

$1 20

line~

*~

metro 25
dac~ tabwrite~ wave

Figure 134: con la number box a destra si può controllare l’ampiezza del tremolo

Rispetto alla Modulazione ad anello, nello spettro è quindi presente anche


il segnale Portante. In figura 135 viene mostrato lo spettro di una modu-
lazione d’ampiezza con Portante di 800 hz e modulante 160 hz. Lo spettro
sarà quindi:

( P f ), ( P f + M f ), ( P f − M f ) =
800, (800 + 160), (800 − 160) =
800, 960, 640
Come nel caso della modulazione ad anello, nella Modulazione d’ampiezza
i segnali possono essere costituiti da suoni complessi. Lo spettro risultante
sarà sempre l’insieme delle somme e differenze fra le frequenze della por-
tante e della modulante e in più le frequenze della portante. La patch in
figura 138 mostra una doppia modulazione d’ampiezza. La portante di
1500 hz viene modulata con un segnale di 500 hz. Il risultato di tale modu-

136
Modulazione d’ampiezza semplice

0 500 1000 1500 2000

Figure 135: Il segnale portante ha frequenza di 800 hz, mentre il modulante ha


frequenza di 160 hz

lazione è la portante di una nuova modulazione con un segnale di 300 hz.


Schematizzando:

( Pf ∗ M1 ) ∗ M2 =
[1500, (1500 + 500), (1500 − 500)] ∗ M2 =
(1500, 2000, 1000) ∗ M2 =
(1500, 2000, 1000) ∗ 300 =
[1500, (1500 + 300), (1500 − 300)], [2000, (2000 + 300), (2000 − 300)],
[1000, (1000 + 300), (1000 − 300)] =
1500, 1800, 1200, 2000, 2300, 1700, 1000, 1300, 700

Lo spettro risultato è mostrato in figura 138.

12.4.1 L’ INDICE DI MODULAZIONE

La patch in figura 136 genera una semplice modulazione d’ampiezza dove


la Portante e le frequenze laterali hanno la stessa ampiezza. Oltretutto im-
postare a zero la frequenza o l’ampiezza della Modulante porterebbe a zero
anche l’ampiezza della Portante, poiché il segnale Portante sarebbe molti-

137
osc~ 800 osc~ 160

expr~ ($v1 * 0.5) + 0.5

*~

$1 20

line~

*~

dac~

Figure 136: la patch che produce lo spettro della figura precedente

plicato per zero. Attraverso un indice di modulazione è possibile controllare


il rapporto fra l’ampiezza della Portante e quella della Modulante.
L’algoritmo per implementare l’indice di modulazione deve assicurare che
l’ampiezza in uscita dall’AM sia sempre pari a 1, quindi al diminuire
dell’ampiezza della modulante ci sarà un aumento della costante che si
somma all’ampiezza della Modulante e che si moltiplica alla Portante. I
figura 139 c’è lo spettro di una modulazione con Portante a 800 hz e Mod-
ulante a 160 hz. Nella figura 140 c’è la relativa patch di Pd.

138
osc~ 1500

osc~ 500

expr~ ($v1 * 0.5) + 0.5

osc~ 300

*~ expr~ ($v1 * 0.5) + 0.5

*~
$1 20

line~

*~

dac~

Figure 137: la patch realizza una modulazione d’ampiezza con due modulanti

139
Modulazione di ampiezza con 2 modulanti

0 1000 2000 3000

Figure 138: la patch che produce lo spettro della figura precedente

Indice di modulazione 0.25

0 500 1000 1500

Figure 139: spettro di modulazione di ampiezza con indice di modulazione pari


a 0.25

140
osc~ 800 osc~ 160
$1 20
expr~ ($v1 * 0.5) + 0.5
line~

expr~ ($v1 * $v2) + (1 - $v2)

*~

$1 20

line~

*~

dac~

Figure 140: la slider verticale a destra controlla l’indice di modulazione, con range
da 0 a 1

141
13 V I B R ATO E M O D U L A Z I O N E D I
FREQUENZA (FM)

13.1 S EGNALE DI CONTROLLO DELLA FREQUENZA : IL VIBRATO

Prima di trattare della Modulazione d’ampiezza avevamo visto che con


un’oscillazione a basse frequenze è possibile modulare l’ampiezza di un
onda producendo un effetto di tremolo. Analogamente, agendo sulla fre-
quenza del segnale con un LFO possiamo modulare la frequenza dell’oscillatore
producendo l’effetto del vibrato. Invece di utilizzare un segnale unipolare
possiamo usare un normale segnale bipolare.

vibrato
osc~ 1

80 40

sig~ *~

+~

osc~

metro 100
dac~ tabwrite~ vibrato

Figure 141

142
Nella patch in figura 141 il segnale bipolare dell’LFO sarà moltiplicato per
40, producendo un’onda che varierà in ampiezza fra -40 e 40 hz. Questo
segnale modulerà la frequenza dell’oscillatore di sinistra che ha una fre-
quenza base di 2000. L’effetto sarà di avere un segnale di frequenza 2000
che oscilla fra 1660 e 2040 hz alla velocità di un ciclo al secondo.

13.2 M ODULAZIONE DI FREQUENZA

Definizione: Dato un segnale Portante e uno Modulante, ha luogo una


modulazione di frequenza (FM) quando il segnale Modulante modula la
frequenza di quello Portante.

Risultato: La FM produce uno spettro molto ricco costituito dal segnale


Portante e da un certo numero di parziali con frequenza pari alla distanza
fra la Portante e un multiplo intero della Modulante. Schematizzando:

FM f = Pf , ( Pf + M f ), ( Pf − M f ), ( Pf + 2M f ), ( Pf − 2M f ), ( Pf + 3M f ), ( Pf −
3M f ), . . .

Come per la modulazione ad anello e d’ampiezza, lo spettro della FM


è simmetrico rispetto all’asse della frequenza Portante, ma contiene un
numero di bande laterali dipendendente dalla deviazione di picco.
La deviazione di picco è ”il massimo mutamento di frequenza che l’oscillatore
portante subisce”1 . La deviazione di picco si stabilisce attraverso un indice di
modulazione secondo la formula:

D
I = Mf

Dove I è l’indice di modulazione e D è la deviazione di picco. Ne consegue


che:

D = I ∗ Mf

Più elevato è il valore dell’indice di modulazione, maggiore sarà la devi-


azione di picco, più numerose le componenti della portante modulata in
frequenza. In figura 142 è mostrata una patch per la modulazione di fre-
quenza semplice. Fa uso di tre subpatch che esaminiamo una alla volta.

1 R. Bianchini, A. Cipriani, "Il Suono Virtuale", ed. Contempo, pag. 244

143
pd modulante

freq indice
200 1000

10

Deviazione
2000

pd portante

freq
4000

pd uscita

dac~

Figure 142: la patch per la modulazione di frequenza semplice

In figura 143 è raffigurata la subpatch per la portante. L’inlet riceve il seg-


nale prodotto dalla modulante, che viene sommato alla frequenza della
portante, che si puòimpostare con la number box in alto.
In figura 144 si puòosservare che la number box a sinistra imposta la fre-
quenza dell’oscillatore modulante. Tale frequenza viene anche moltiplicata
per l’indice di modulazione. Il prodotto di tale moltiplicazione determina la
deviazione di picco, quindi l’ampiezza dell’oscillatore modulante. Il segnale

144
freq
0

inlet~

+~

osc~

outlet~

Figure 143: la subpatch per il segnale portante

in uscita dall’outlet entra nell’inlet della Portante.

Sulla patch per l’uscita (fig. 145) non c’è molto da dire: una slider verticale
controlla l’ampiezza del segnale prodotto dalla FM.
Maggiore è la deviazione di picco, maggiore sarà il numero di componenti
presenti nello spettro. In figura 146 l’indice di modulazione pari a 0.1
determina una deviazione di picco di 20 hz (0.1 * M f , ovvero 0.1 * 200 = 20)
quindi un numero esiguo di componenti spettrali. In figura 147 l’indice
pari a 10 determina una devizione di 2000 hz, quindi uno spettro molto
più ricco: nella banda di frequenza compresa fra (Pf − D) e (Pf + D)
(2000 - 6000) le ampiezze grosso modo si equivalgono mentre al di sotto e al
di sopra di tali limiti inizia una diminuzione graduale delle ampiezze.

13.2.1 L’ INVILUPPO

Fino ad ora il risultato delle operazioni ha sempre prodotto segnali con-


tinui. Non ci siamo occupati di definire un evento nel dominio del tempo,
che fosse provvisto di un inizio e di una fine, come invece accade per ogni
suono reale. Con gli strumenti digitali abbiamo la possibilità di creare
suoni di durata indefinita, ma anche di definire la loro durata nel tempo.
Per disegnare un suono definito nel dominio del tempo abbiamo bisogno
di un inviluppo, ovvero di un profilo che determini la forma che il suono

145
freq indice
200 1000

10

Deviazione
2000

t b f

/ 100 *
osc~ 200 $1 20 $1 20

line~ line~

*~

*~

outlet~

Figure 144: la subpatch per il segnale modulante

assume rispetto al tempo. In figura 148 si può osservare la forma d’onda


prodotta da un suono di tromba della durata di circa 6 decimi di secondo.
Approssimando molto si può distinguere una fase (attacco in cui l’onda
passa da uno stato di quiete ad uno di massima ampiezza, una seconda
fase in cui c’è un calo dell’ampiezza (decadimento), una terza fase in cui il
suono si mantiene più o meno costante (sostegno) e un’ultima fase (rilascio)
in cui l’onda torna allo stato di quiete. Queste quattro fasi, a volte indicate
con l’acronimo ADSR, costituiscono l’inviluppo del suono.
Naturalmente l’ADSR costituisce un’approssimazione, ci sono nella realtà
dei suoni che non hanno la fasi di sostegno o quella di decadimento, ad
esempio alcuni suoni percussivi. Sicuramente però l’attacco e il rilascio
del suono sono nei suoni reali sempre presenti. Nella musica elettronica

146
$1 20
inlet~
line~
*~

outlet~

Figure 145: la subpatch per l’uscita

Spettro FM indice 0.1

0 1000 2000 3000 4000 5000 6000 7000 8000

Figure 146: FM con frequenza portante di 4000 hz, modulante di 200 hz e indice
di modulazione 0.1

un esempio tipico di inviluppo è quello mostrato in figura 149(b), che viene


applicato al segnale (a), producendo la forma d’onda mostrata in (c).
Uno degli strumenti per generare inviluppi in Pd è l’oggetto envgen che ci
consente di disegnare inviluppi costituiti da segmenti. L’output dell’oggetto
è un messaggio leggibile con line (fig. 150). Nella prossima sezione faremo
uso di generatori di inviluppo nella modulazione di frequenza.

147
Spettro FM indice 10

0 1000 2000 3000 4000 5000 6000 7000 8000

Figure 147: FM con frequenza portante di 4000 hz, modulante di 200 hz e indice
di modulazione 10

Inviluppo di tromba
ampiezza

tempo

Figure 148

13.2.2 FM A SPETTRO VARIABILE

Un uso interessante della modulazione di frequenza è quello di usare degli


inviluppi per creare spettri variabili. Con la prossima patch generiamo una

148
a)

b)

c)

Figure 149: l’inviluppo disegnato in (b) ha valori compresi fra 0 e 1. L’onda (a)
viene inviluppata da (b), ovvero istante per istante le ampiezze is-
tantanee di (a) vengono moltiplicate per i relativi valori di (b), pro-
ducendo (c)

sequenza di suoni brevi che simulano il timbro di un woodblock, secondo


un algoritmo proposto da John Chowning2 .
L’algoritmo è semplice: una FM con portante di 80 hz e modulante di
55 hz. Un indice di modulazione gestito da un inviluppo con una punta
massima di 25 e un altro inviluppo per l’ampiezza del suono. In figura
151 c’è l’intero algoritmo. La durata di un evento è di 200 millisecondi.
La subpatch pd indexenv serve semplicemente a rescalare i valori in uscita
dell’oggetto envgen che emette solo valori di ampiezza compresi fra 0 e 1
(fig. 152. La subpatch envamp invece memorizza i dati del’altro envgen e li
spedisce a line senza alcun riscalamento.
2

149
Figure 150: l’oggetto envgen

Infine in figura 154 c’è il sequencer per la generazione dei bang per in-
nescare gli eventi sonori. L’oggetto list-idx riceve una lista di 0 e 1, 1 laddove
l’evento deve essere on, 0 quando dev0essere off. metro collegato a un con-
tatore costringe list-idx ad emettere uno ad uno i valori della lista, quando
il valore è uguale a uno la patch invia un bang agli inviluppi, creando la
sequenza desiderata.

13.3 P ORTANTI MULTIPLE

Fino ad ora abbiamo implementato la Modulazione di Frequenza facendo


uso di un oscillatore portante e di uno modulante. Questo modello, facendo
uso appropriato di inviluppi e del controllo dei rapporti di frequenza e di
indice di modulazione può produrre timrbi molto complessi e interessanti,
ma la FM può anche essere realizzata ampliando il campo degli attori in
gioco. Ad esempio se con un un’unica onda modulante si modulano più
portanti lo spettro risultante sarà ancora più complesso.

Nella figura 155 un’unica modulante agisce su tre portanti delle quali si
può impostare la frequenza ma che hanno un unico controllo dell’ampiezza.

Il modello della FM a portanti multiple diventa estremamente complesso


se si controllano le singole ampiezze delle portanti con inviluppi diversi.
In figura 156 quattro envgen controllano rispettivamente le tre ampiezze

150
r dur r trig
osc~ 55
duration $1 dump r envindex

*~ 55

*~

+~ 80

osc~

pd indexenv
loadbang
r dur r trig
200
duration $1 dump r envamp
200

*~ s dur

dac~

pd envamp

pd seqz

START SPEED
150

Figure 151: la patch per l’FM semplice di Chowning

delle portanti e l’indice di modulazione.

151
inlet inlet

prepend set
unpack f f

* 25 loadbang

pack f f 1 16 0 184 0

line~ 0 5 s envindex

outlet~

Figure 152: La subpatch per il riscalamento dei valori di envgen. Le ampiezze


vengono scalate in un range fra 0 e 25. La parte destra della patch
serve a memorizzare i dati disegnati in envgen. L’help dell’oggetto
spiega come salvare i dati.

inlet
inlet
line~
prepend set
outlet~
loadbang

0.807143 17 0.95 15 1 15.0001 0.971429 7.99998 0.914286


3.99979 0.792857 18.0001 0.35 22.9999 0.142857 41.0006
0.0142857 58.9995 0

s envamp

Figure 153: la subpatch envamp

13.4 M ODULANTI MULTIPLE

Allo stesso modo si può aumentare il numero delle modulanti che agiscono
su un’unica portante. Nella figura 157 tre oscillatori modulanti agiscono
su un’unica portante.

Tale configurazione, come quella precedente, è solo una delle tantissime


possibili. Lasciamo il lettore sperimentare qualche soluzione diversa, con-

152
r trig

START SPEED
150

pack 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

list-idx metro 250

sel 1 int 0 + 1
s trig mod 16

Figure 154: la subpatch seqz

trollando indici di modulazione con envgen e aumentando il numero delle


modulanti (o delle portanti).

153
frq frq frq frq index
250 500 750 50 90

pd mod

pd carrier pd carrier pd carrier

$1 20

line~

*~

dac~

Figure 155: FM con portanti multiple

154
bang duration 1000

index

line~ line~ line~ line

* 200

frq frq frq frq


250 500 750 50

pd mod

pd carrier pd carrier pd carrier

*~ *~ *~

*~ 0.3

dac~

Figure 156: FM con portanti multiple con controllo di singole ampiezze e indice
di modulazione tramite envgen

155
pd modulante pd modulante pd modulante

freq indice freq indice freq indice


40 500 160 230 320 400

5 2.3 4

Deviazione Deviazione Deviazione


200 368 1280

+~

+~

pd portante

freq
80

pd uscita

dac~

Figure 157: FM con modulanti multiple

156
14 INTRODUZIONE ALLA SINTESI
GRANULARE

14.1 T EORIA DELLA SINTESI GRANULARE

La sintesi granulare muove dal concetto che eventi sonori molto brevi,
emessi in rapidissima successione, perdono la loro singolarità e costitu-
iscono un continuum sonoro unitario.

Tali brevi segmenti sonori sono detti grani, o quanta sonori. Un flusso
continuo di grani costituisce un treno, mentre più treni contemporanei for-
mano nuvole.

Il grano è l’unità elementare su cui si basa questa tecnica di sintesi. Esso è


dotato di forma d’onda e inviluppo di ampiezza. Entrambi questi parametri
assumono caratteri molto eterogenei: la forma d’onda può essere di qualunque
tipo, mentre l’inviluppo, per ragioni computazionali, ha tipicamente, ma
non necessariamente, forma simmetrica (158).
In figura 159 troviamo un segnale con forma d’onda sinusoidale invilup-
pato da una forma a campana e da una forma trapezoidale. Il risultato sono
due grani simmetrici.
Il flusso di grani costituisce i treni, il cui principale carattere distintivo è la
densità per secondo, che si misura in hertz. Tale densità definisce il periodo,
cioè l’intervallo fra l’inizio di un grano e l’inizio del successivo. Il periodo
è costituito dal grano e da una certa quantità di silenzio (s, fig. 160). La
durata del periodo è inversamente proporzionale alla densità (fig. ??).

14.1.1 DIPENDENZA VS . INDIPENDENZA DEI PARAMETRI

Densità dei grani e durata del grano sono due parametri che possono es-
sere o meno dipendenti l’uno dall’altro. Quando all’aumentare della den-
sità dei grani diminuisce la durata del singolo grano densita e durata del
grano sono parametri dipendenti. In questo caso il rapporto di inversa
proporzionalità rimane costante. Nel caso di indipendenza dei parametri

157
!"#$%&'( )(##
upg upg

gpg gpg

*+",(-.&/"# *+&"'01#"+
upg upg

gpg gpg

21"&z0"1%%&"' ,1#%(
upg upg

gpg

gpg

Figure 158: Possibili inviluppi di un grano

invece all’aumentare della densità dei grani, diminuisce il periodo, ma la


durata del grano rimane costante. In tal caso il rapporto fra la durata del
grano e la porzione di silenzio cambia in favore della durata del grano
e quando la densità dei grani raggiunge un certo limite e il periodo di-
venta minore della durata del grano si ha un fenomeno di troncamento,
che viene sublimato attraverso la tecnica dell’overlapping di cui ci occuper-
emo fra poco.

In figura 161(a) con densità pari a 25 hz e durata del grano (gdur) di 20 mil-
lisecondi, si ha un periodo di 40 millisecondi. Quando la densità aumenta
a 50 hz, come in (b), periodo e gdur coincidono, quindi è il limite entro il
quale i grani ancora non si toccano. Quando la densità supera quella soglia,
come nell’esempio (c), dove è di 70 hz, il periodo diventa minore di gdur e
si realizza il troncamento: il grando inizia prima che il precedente sia ter-
minato. Nell’ultima situazione, la (d), si applica un overlapping per evitare

158
sine wave
1,0

0,0

-1,0

bell envelope trap envelope


1,0 1,0

0,0 0,0

-1,0 -1,0

resulting grain resulting grain


1,0 1,0

0,0 0,0

-1,0 -1,0

Figure 159: Sinusoide con inviluppi a campana e trapezoidale

il clicking determinato dal troncamento.

14.1.2 OVERLAPPING

L’overlapping consiste nella somma di treni diversi di grani. Nel momento


in cui il periodo è minore della durata del grano è necessario sdoppiare il
treno di grani in due o più treni in modo da evitare il troncamento degli
stessi.

Nella situazione mostrata in figura 162, quando gdur è uguale a 50 ms


e gdens a 50 hz il periodo è pari a 20 ms. Questo significa che ogni 20
ms (parametro che chiameremo offset un nuovo grano fa la sua comparsa,
quindi prima che un grano termini, altri due ne sono comparsi.

L’overlapping si realizza creando tre treni di grani, ognuno con la stessa


densità, ma con un suo offset. Potremmo dire che ogni treno avrà una fase

159
Figure 160: Periodo e densità del grano

diversa. Nel caso dell’immagine in figura 162 il primo treno avrà offset
zero, il secondo 20 ms, il terzo 40 ms. per ogni treno il periodo avrà durata
di 60 ms.

Il numero dei treni necessari per realizzare l’overlapping è un numero intero


detto overlapping factor e si calcola dividendo innanzitutto 1000 (i millisec-
ondi in un secondo) per la densità, operazione che ci dà l’offset, poi divi-
dendo la durata del grano per l’offset appena ottenuto ed eventualmente
approssimando all’intero superiore. In C scriveremmo la seguente fun-
zione:

int overfactor (gdur, gdens) {

float offset, factor;


int overlapfactor;

offset = 1000.0 / gdens;


factor = gdur / offset;

160
Figure 161: Troncamento e Overlapping

if (factor - (int)factor == 0.0) {


overlapfactor = int(factor);
else {

161
pdur: 60ms
gdur: 50ms gdens: 50hz

offset1: 20ms
offset2: 40ms

Figure 162: Overlapping dei treni

overlapfactor = int(factor)+1;
}
}
}

Nella figura 163 si vede la rappresentazione di una situazione con gdens


pari a 50 hz, gdur di 45 ms, con relativo offset di 20 ms e overlapping factor
di 3.

14.1.3 PARAMETRI E SPETTRI RISULTANTI

Data la complessità e la varietà delle possibilità realizzabili con la sintesi


granulare, non è agevole descrivere gli spettri risultanti da questa tecnica.
A parità di densità ad esempio, un cambio di durata del grano può cam-
biare sensibilmente lo spettro del suono risultante. A parità di densità e
durata del grano, un cambio dell’inviluppo del grano o della sua forma
d’onda può produrre risultati diversissimi. I parametri che contribuiscono
alla formazione di uno spettro sono tantissimi e se si pensa che la densità
dei grani può essere un parametro variabile nel tempo le possiblità combi-
natorie diventano praticamente infinite.

Consideriamo l’inviluppo del grano. Se l’inviluppo fosse l’unica forma


disponibile, cioè se dentro l’inviluppo ci fosse segnale nullo, con densità

162
Figure 163: Overlapping con overlapping factor pari a 3

superiore alla soglia udibile (oltre i 20hz circa) si produrrebbe già un suono
ben distinguibile.

In sostanza, ogni parametro contribuisce alla formazione del suono, quindi


nell’implementazione della sintesi granulare vanno trattati con attenzione
i seguenti parametri:

• durata del grano (gdur)

• inviluppo del grano (grainenv)

• densità del treno (gdens)

• rapporto gdens/gdur

• variabilità nel tempo di gdens e degli altri parametri

163
14.1.4 I L DOMINIO DEL TEMPO E LA SINTESI GRANULARE

Nell’implementare la sintesi granulare è necessario fare delle scelte in mer-


ito al tipo di sintesi che si vuole realizzare. Prima di tutto bisogna de-
cidere se gdens e gdur saranno parametri dipendenti o indipendenti fra loro.
Nel primo caso sarà necessario realizzare un algoritmo per l’overlapping, e
questo vale per la maggiorparte dei tipi di sintesi granulare, nel secondo
caso no, perché all’aumentare della frequenza, diminuirà la durata del
grano. Questo secondo caso è implementato grazie alla cosiddetta Grainlet
Synthesis.
La seconda scelta iniziale da fare consiste nell’optare per una densità costante
nel dominio del microtempo o per una densità variabile.

Il microtempo è quella dimensione nell’ambito della quale non c’è una


percezione dei cambiamenti temporali, ma timbrici. Se si sceglie di variare
la durata del periodo nell’ambito di 10 ms, cioè se si applica una variazione
alla densità comprsa fra [-5,+5]ms rispetto alla frequenza stabilita, non si
avrà percezione di tale cambiamento se non nel dominio del timbro.

Timbro e tempo sono due parametri strettamente connessi. Come sappi-


amo la frequenza è direttamente proporzionale al tempo, la sua unità di
misura (l’hertz) indica la velocità con cui un’onda compie il suo ciclo. Nat-
uralmente a frequenza alta non abbiamo nessuna percezione temporale,
ma una totale percezione timbrica. C’è però una zona confusa, quella com-
presa fra i 20 e i 40 hz circa, dove la percezione si divide fra timbro e
tempo, perché gli eventi sono vissuti come ritmici e dove all’aumento della
frequenza corrisponde la sensazione di una precipitazione ritmica, fino a
superare una certa soglia, oltre la quale il ritmo non viene più percepito.

Possiamo distinguere, generalizzando molto, tre tipi di tempo (fig. 164), dal
più indistinguibile, il tempo microscopico, fino al tempo formale, che dal punto
di vista percettivo ha una dimensione fenomenica piuttosto che temporale,
attiene quindi alla capacità del percettore di ricostruire soggettivamente la
sequenza degli eventi.

Quando si realizza una sintesi granulare in cui nel microtempo la densità


dimane costante, si ha la sintesi granulare sincrona (Syncronous Granular
Synthesis), mentre in presenza di densità variabile nel microtempo si ha la
sintesi granulare asincrona Asyncronous Granular Synthesis. Nel primo caso

164
tempo
dominio del timbro
microscopico

tempo
dominio del tempo musicale
macroscopico

tempo
dominio del tempo culturale
formale

Figure 164: I domini del tempo

si parla a volte di Quasi-Syncronous Granular Synthesis perché la densità


non varia nel microtempo, ma può variare nel dominio del tempo percepi-
bile. Se ad esempio implementiamo un algorimo dove decidiamo che la
densità passa da 50 a 100 hz in 10 secondi, si ha una percezione ben dis-
tinta del cambiamento, ma nel microtempo possiamo dire che non ci sono
cambiamenti.

Syncronous (Quasi-Syncronous)
Asyncronous Granular Synthesis
Granular Synthesis

Sampled Sounds
Trainlet Synthesis Grainlet Synthesis Glisson Synthesis
Granulation

Pulsar Synthesis FOF Synthesis

Figure 165: Alcune tipologie di Sintesi Granulare

La complessità generata dalla combinazione dei parametri ha dato vita,


storicamente, ha molti tipi di sintesi granulare. Da Gabor a Curtis Roads,
passando per Xenakis, sono stati implementati diversi tipi di Granulazione,
semplicemente agendo sull’idea generale di treni di grani combinati in
modi diversi. Nella figura 165 proponiamo uno schema riassuntivo di al-
cuni dei più importanti tipi di sintesi granulare, collegando per sommi

165
capi le famiglie tipiche e le relative derivazioni.

14.2 I MPLEMENTAZIONE IN PD

La prima cosa da fare è creare un algoritmo che generi le tabelle per


l’inviluppo del grano. Usando come di consueto gli oggetti tabread (fig. ??).
In questo esempio la patch genera quattro diverse forme per l’inviluppo:
una campana, una forma trapezoidale, una mezza sinusoide e una curva
esponenziale.

14.3 U N ESEMPIO DI Trainlet Synthesis

Il primo tipo di sintesi granulare che implementiamo è una Trainlet Synthe-


sis semplificata: gdur e gdens sono strettamente dipendenti l’una dall’altra,
per l’esattezza inversamente proporzionali. Ne consegue che all’aumentare
della densità, diminuisce la durata del grano. Si tratta di una sintesi sin-
crona con parametri dipendenti. Quello che si può pilotare in questa patch
è:

• densità dei grani in hz

• frequenza all’interno del grano

• forma dell’inviluppo

La durata del grano gdur naturalmente non è impostabile perché dipende


da gdens.

Cerchiamo di capire cosa accade all’interno della patch (fig. 166). L’oggetto
tabread4∼ legge la tabella dell’inviluppo del grano. phasor∼ alla fre-
quenza scelta moltiplica la sua uscita per 512, in modo da leggere i 512
indici della tabella. L’inviluppo viene moltiplicato per il segnale generato
da osc∼.
Se si realizza questa semplice patch la cosa più interessante è verificare la
differenza di timbro a parità di frquenza e densità, al variare della forma
dell’inviluppo.

166
pd frequenza
pd envelope
phasor~ 4 r frq
inviluppo
expr 1000 / $f1
set bell
s graindur
*~ 512 set trap

set halfsine
r princfrq
set expdec

osc~ 440 tabread4~ bell

frequenza
467
*~ densità
r amp
30
$1 50

line~
amp graindur
33.33
*~

dac~

Figure 166: Implementazione della Trainlet Synthesis

14.4 L A Pulsar Synthesis

La Pulsar Synthesis prende il nome da un tipo di stella che emette impulsi


di radiazioni a intervalli regolari. Questa tecnica di sintesi è relativamente
simile alla Trainlet Synthesis, ma si basa sul principio della variabilità del
rapporto fra gdur e s all’interno del periodo. È quindi una tecnica sincrona
con parametri dipendenti, anche se esitono implementazioni a parametri
indipendenti.

L’elemento informativo più importante è il pulsaret, costituito da un peri-


odo in rapporto inverso rispetto alla densità. Tale periodo contiene il grano
e un frammento di silenzio. il rapporto fra queste due misure è detto Duty
Cycle.

L’algoritmo è simile a quello che abbiamo implementato per la Trainlet


Synthesis, ma in questo caso è importante che l’oggetto phasor∼ invia un

167
segnale a tabread4∼ tale che ci sia dopo il grano una porzione di silenzio.
Cerchiamo di spiegare meglio questo concetto. In presenza di una tabella
di 512 punti un phasor∼ con frequenza 1 con moltiplicazione del segnale
per 512 leggerà tutta la tabella in un secondo. Cosa accade se moltiplichi-
amo il segnale in uscita da phasor∼ per 1024? In un secondo il suo segnale
creerà una rampa da 0 a 1023. Fino a quando il valore sarà minore di 512
leggerà i valori della tabella, oltre 512 leggerà valori pari all’ultimo indice
letto nella tabella (che andrà SEMPRE impostato a zero). Raddoppiando
quindi il valore dei punti da far leggere a phasor∼ si genera un Duty Cycle
di 1:1, una parte di grano e una uguale di silenzio.

Figure 167: Duty Cycle con phasor∼

168
In figura 167 viene mostrato un Duty Cycle di 1:3. phasor∼ viene molti-
plicato per 2048, il quadruplo della tabella da leggere, quando il valore in
uscita è minore di 0.25 leggerà tutti i valori della tabella, oltre 0.25 non
leggerà più nulla e tabread4∼ emetterà l’ultimo indice.

Nell’algoritmo è di fondamentale importanza implementare il calcolo del


Duty Cycle. Poniamo di poter impostare il Duty Cycle con uno slider che
agisce nel range [0,1], dove 0.5 rappresenta il rapporto di 1:1, 0.25 il rap-
porto di 1:3, 0.75 il rapporto 3:1 e così via. Basta dividere la dimensione
della tabella per la quantità impostata con lo slider per ottenere la giusta
misura per cui moltiplicare l’uscita di phasor∼. In linguaggio di pd, costru-
endo una piccola subpatch ci troveremo di fronte all’immagine di figura 168.

inlet ratio

expr 512 / $f1

$1 50

line~

outlet~ ratio

Figure 168: Calcolo del Duty Cycle

la patch per l’implementazione della Pulsar Synthesis appare nella figura


169. A parte la scelta del Duty Cycle, per il resto è molto simile alla patch
per la Trainlet Synthesis, quindi si può scegliere la densità dei grani e la
frequenza interna al grano, nonché il rapporto grano/silenzio.

Il comportamento spettrale della Pulsar Synthesis è tale che all’ aumentare


della quantità di s tende all’entropia, cioè ad uno spettro molto ampio con
ampiezze estremamente omogenee. Lo spettrogramma della figura 170 e
il sonogramma di figura 171 ne sono prova visibile.

169
frequenza
0 0

phasor~ 4 pd ratio 0

choose envelope shape

set bell

osc~ 880 *~ set trap

set halfsine

set expdec
tabread4~ trap

*~ $1 50

line~

*~

dac~

Figure 169: Implementazione della Pulsar Synthesis

14.5 Asyncronous Granular Synthesis

La Asyncronous Granular Synthesis si realizza intervenendo sulla densità dei


grani in modo da renderla variabile nel contesto del tempo microscopico.

Per implementarla in modo semplice si può realizzare una subpatch inter-


venga sulla frequenza del solito phasor∼ variandone la frequenza entro un
range di valori prestabilito (fig. 172).

L’inlet di sinistra riceve la frequenza di base mentre quello di destra l’indice


di variazione. Tale misura rappresenta, in percentuale, l’ambito entro il
quale deve avvenire la variazione. Se, per esempio, si stabilisce una vari-
azione del 50% con frequenza base 16 hz, la variazione sarà di 8 hz, quindi

170
Figure 170: Lo spettro risultante della Pulsar Synthesis

la densità sarà variabile nel range [12,20]hz.

Tipicamente, la sintesi granulare asincrona generalizza il concetto di vari-


azione nel dominio del microtempo. Non solo la densità dei grani può essere
variabile, ma anche tutti gli altri parametri. Nella nostra patch completa si
possono impostare i seguenti parametri, con relativo indice di variazione:

• densità dei grani

• frequenza interna al grano

• ampiezza

• distribuzione sul fronte stereo

In figura 173 osserviamo la patch nella sua forma finale.

171
7500

Frequency (Hz)

0
0 11.42
Time (s)

Figure 171: Il sonogramma risultante della Pulsar Synthesis

inlet gdens inlet %

noish~ expr ($f1 * $f2) / 200

sig~ *~ 0

+~

phasor~

*~ 512

outlet~ gdens

Figure 172: Variazione di gdens

La patch contiene due grandi subpatch, una per la gestione di tutti i parametri
dei grani, l’altra per la gestione dell’ampiezza e la distribuzione sul fronte

172
ampenv
gdens bell pd envelope
trap
34
halfsine
expdec
gdensvar_(0-100) amp_(0-1)

waves
30.30 1
sine
%_ampvar_(0-100)
rect
frq
tri
475 saw
48.48
frqvar_(0-100)
stereospread

20.20
0.505

*~

*~ *~ pd reverb

1 1
throw~ rev1
throw~ rev2

dac~

Figure 173: La patch che implementa la sintesi granulare asincrona

stereo. In basso un’ulteriore subpatch permette di impostare un riverbero.

La subpatch deputata alla gestione dei grani ha come centro vitale un


oggetto phasor∼ (fig. 174)che riceve la frequenza, variata com l’implementazione
che abbiamo visto in figura 172. Analogamente la frequenza interna all’oscillatore
viene impostata nello stesso modo e l’indice di variazione può essere rego-
lato tramite una slider. Questa subpatch si occupa anche di permettere la
selezione dell’inviluppo del grano e della forma d’onda interna al grano.
In questo secondo caso si tratta di semplici tabelle che contengono la forma
d’onda (fig. 175). L’uscita di phasor∼ infine, invia il suo segnale attraverso
throw∼ in modo che l’altra subpatch possa riceverlo ed usarlo come trigger.

173
ampenv
gdens bell
trap
34
halfsine
expdec
gdensvar_(0-100)

waves
30.30
sine
rect
frq
tri
475 saw

frqvar_(0-100)

20.20 noish~ expr ($f1 * $f2) / 200

sig~ *~ 0

r waveform
+~ noise~
sel 0 1 2 3
phasor~
expr ($f1 * $f2) / 200
set bell
*~ 512
set trap
set halfsine tabread4~ bell
samphold~ r waves
set expdec
sel 0 1 2 3
sig~ *~ 0
set osc
+~ set rect

pd waves set tri

*~ set saw

outlet~ throw~ phas

Figure 174: La subpatch per la gestione dei grani

L’altra subpatch riceve con chatch∼ il segnale di phasor∼ dell’altra sub-


patch. Due oggetti samphold∼ servono l’uno a produrre la variazione di
ampiezza, l’altro la distribuzione stereo (fig. 176). Quest’ultima parte
dell’algoritmo, in basso a destra, funziona in modo tale da produrre ad
ogni campionamento di samphold∼ un valore casuale compreso fra [-1,1].
Tale valore, in uscita, viene moltiplicato per l’indice del fronte stereo (com-

174
loadbang

inlet~ inlet ;
saw sinesum 515 -1 -0.5 -0.33 -0.25 -0.2 -0.16 -0.142
-0.125 -0.111 -0.1 -0.09 -0.083 -0.076 -0.071 -0.066
-0.0625;
saw normalize 1

tabosc4~ osc ;
tri sinesum 515 1 0 -0.111111 0 0.04 0 -0.0204082 0
outlet~ 0.0123457 0 -0.00826446 0 0.00591716 0 -0.00444444;
tri normalize 1

;
table osc 515
rect sinesum 515 1 0 0.333333 0 0.2 0 0.142857 0 0.111111 0
table rect 515 0.0909091 0 0.0769231 0 0.0666667 0;
table tri 515 rect normalize 1;
table saw 515 ;
osc sinesum 515 1

Figure 175: Le tabelle per la forma d’onda interna al grano

preso fra [0,1]). Questo significa che se l’indice è impostato a 0 produrrà


valori nulli, se impostato a 1 manterrà i valori originali [-1,1]. L’oggetto
successivo riscala tali valori nel range [0,1] e successivamente tali valori
vengono distribuiti fra canale destro e sinistro. Se l’indice di variazione
stereo è impostato a zero, i valori in uscita saranno sempre pari a 0.5,
quindi distribuiti equamente fra canale destro e sinistro. Se invece l’indice
è 1 i valori si muoveranno iberamente fra destra e sinistra.

14.5.1 vline∼

Prima di proseguire con la disamina di alcuni metodi di implementazione


della sintesi granulare, esaminiamo un oggetto molto potente che ci sarà
utile fra poco. Si tratta di vline∼, che produce rampe come line∼ ma
che è in grado di agire a livello di campioni, quindi in modo più preciso e
rapido di quest’ultimo. L’oggetto accetta in entrata terne di valori: target,
tempo di raggiungimento e delay, dove target è il valore da raggiungere, tempo
di raggiungimento è il tempo in millisecondi per raggiungerlo e delay è il
ritardo con cui iniziare la rampa rispetto all’attivazione. L’oggetto può
accettare anche target multipli, con gli altri argomenti relativi separando
con la virgola le terne di valori. Se volessimo creare un inviluppo come
quello mostrato nella figura 177 dovremmo ragionare in questo modo:

• Vai da 0 a 1 in 50 millisecondi iniziando subito (0, 1 50 0)

175
catch~ phas
amp_(0-1)
noise~

1 samphold~
%_ampvar_(0-100)
abs~ / 100

*~ 0 $1 20
48.48

stereospread expr~ 1 - $v1 line~

0.505
*~ noise~

samphold~

outlet~ amp
*~ 0

expr~ ($v1 * 0.5) + 0.5

expr~ 1 - $v1 sqrt~

sqrt~

outlet~ sx outlet~ dx

Figure 176: La subpatch per ampiezza e panning

• Resta a 1 per 100 millisecondi a partire dal millisecondo 50 (1 100 50)

• Vai a 0 in 150 millisecondi iniziano al millesecondo 150.

Nella lingua di pd, con vline∼ dovremmo implementare come in figura


178.

14.5.2 RENDERE INDIPENDENTE IL PARAMETRO gdur

Anche nell’implementazione precedente la durata del grano è inversamente


proporzionale alla densità dei grani. Per far si che anche tali parametri

176
Figure 177: Un inviluppo da generare con vline∼

0, 1 50 0, 1 100 50, 0 150 150

vline~

Figure 178: L’inviluppo della figura 177 realizzato con vline∼

siano indipendenti è necessario svinvolarli l’uno dall’altro in modo che si


possa impostare gdur e renderla fissa al variare della densità.

Per implementare questo algoritmo è necessario fare uso di vline∼ per


generale una rampa che legga la tabella dell’inviluppo e controllarla con
un oggetto che sia indipendente dal trigger principale, cioè il phasor∼ che
controlla la densità dei grani.

Il limite di questa implementazione risiede nel fatto che vline∼ viene at-
tivato tramite un bang e non tramite segnale, quindi a velocità molto alte
potrebbe peccare in precisione. Per quello che è stato fatto fino ad ora,
sappiamo che l’oggetto che produce bang a intervalli prestabiliti è metro,
che potrebbe rappresentare una buona soluzione, ma non ottimale perché
quello che ci occorre veramente è la possibilità di emettere un bang alla
frequenza del phasor∼ che controlla la densità dei grani, che, come sappi-

177
amo, è variabile nell’ambito del microtempo.

Per implementare tale sistema si può usare l’oggetto edge∼, della libreria
cyclone, che clona gli oggetti di MaxMSP. Questo oggetto emette un bang
dall’outlet sinistro ogni volta che il segnale in entrata passa da zero a non-
zero e un bang dal destro quando il segnale passa da non-zero a zero. L’help
dell’oggetto mostra un esempio di utilizzo.

In questo modo un unico oggetto phasor∼ controlla la densità dei grani e


allo stesso tempo innesca vline∼ per la lettura della tabella dell’inviluppo
del grano. Come nella patch della sezione precedente lo stesso oggetto con-
trollerà la distribuzione stereo e l’ampiezza dei singoli grani. La figura 179
riassume l’algoritmo della patch.

phasor~

amplitude
grain density grain triggering stereo spreading
variation
(gdens) (edge~) (samphold~)
(samphold~)

grain duration
(vline~/tabread~)

Figure 179: Schema generale dell’algoritmo per la gestione indipendente dei


parametri

La subpatch per l’innesco di vline∼ tramite edge∼ è mostrata in figura 180.


L’oggetto expr∼ riceve il segnale e lo processa in modo che restituisca 1
se il segnale è minore di 0.5, zero se maggiore. edge∼ produrrà un bang
a sinistra quando il segnale passerà da zero a non-zero, cioè ogni volta
che phasor∼ conclude un ciclo e ricominci la sua rampa da zero. Il bang
emesso da edge∼ innesca l’oggetto float che restituisce la durata del grano
e attiva l’oggetto vline∼ in modo che quest’ultimo crei la rampa da 0 a 1
in 20 ms (il tempo di default). Naturalmente una number box consente di

178
cambiare a piacimento la durata del grano.

phasor~ 8

expr~ $v1 < 0.5

edge~ 0

f 20

0, 1 $1

vline~

*~ 512

tabread4~ bell

Figure 180: La subpatch per l’innesco di vline∼

Una volta resi indipendenti densità e durata dei grani c’è il rischio che a
densità alta avvenga un troncamento fra i grani, quindi è necessario im-
plementare un algoritmo per l’overlapping. La soluzione per questa patch è
semplice, anche se computazionalmente dispendiosa: invece di attivare un
nuovo treno di grani quando il fattore do overlapping lo richieda, creiamo
più treni a prescindere e tramite un contatore inneschiamo un grano alla
volta per ogni treno.

La figura 181 mostra un esempio di questo procedimento, con tre treni.


Sopra l’overlapping factor non produce sovrapposizione di grani, in basso
il fattore 2 provoca sovrapposizione di due grani. In entrambi i casi i tre
treni sono attivi a turno.
In pd l’algoritmo per implementare tre treni come nella figura precedente
è mostrato in figura 182. Un contatore invia il suo conteggio all’oggetto %
che calcola il modulo in modo da restituire il conto da 0 a 2, sel indirizza i
bang ai tre treni, zero attiva il primo treno, 1 il secondo, 2 il terzo.

179
overlapping factor: 1

train 0

train 1

train 2

overlapping factor: 2

train 0

train 1

train 2

Figure 181: Overlapping con tre treni

Naturalmente questo procedimento può essere realizzato anche per atti-


vare molti più treni. I limiti sono determinati dalla capacità di calcolo del
computer e dal fatto che in pd i dati di controllo sono meno affidabili dei
segnali, che hanno sempre la precedenza.

A questo punto la patch per la sintesi granulare asincrona con parametri in-
dipendenti può essere implementata. La figura 183 mostra l’interfaccia per
il controllo dei parametri. Nelle properties di ogni GUI e di ogni number box
sono impostati, tramite send-symbol, i nomi degli oggetti che riceveranno i
relativi dati.
L’interno della patch è mostrato in figura 184. I treni attivi sono otto, per il
resto la patch è uguale a quella implementata per la sintesi asincrona con
parametri dipendenti (sez. 14.5) quindi lasciamo al lettore il compito di
analizzarla. In figura 185 è mostrato l’interno della subpatch envgen dove

180
phasor~

expr~ $v1 < 0.5

edge~

f + 1

% 3 gdur
0
sel 0 1 2

f 20 f 20 f 20

0, 1 $1 0, 1 $1 0, 1 $1

vline~ vline~ vline~

*~ 512 *~ 512 *~ 512

tabread4~ bell tabread4~ bell tabread4~ bell

Figure 182: Overlapping con tre treni

gdens gdensvar_(0-100) waveform envform


0
osc bell
frq gdensvar_(0-100) rect trap
0 tri halfsine
gdur saw expdec

amp_(0-1) Reverb

ampvar_(0-100) gain

amp_(0-1) feedback

Figure 183: Interfaccia per il controllo dell’Asyncronous Granular Synthesis con


parametri indipendenti

abbiamo incapsulato ogni generatore di treni.

181
r gdens r gdensvar

t f f f r eform

sig~ noish~ expr ($f1 * $f2) / 200 sel 0 1 2 3

*~ 0
set bell
+~
set trap

set halfsine
phasor~ set expdec
r frq r frqvar

expr~ $v1 < 0.5 throw~ phas s envform


noise~ expr ($f1 * $f2) / 200

samphold~ r waves edge~

sel 0 1 2 3 f + 1 noise~
sig~ *~ 0
set osc % 8

+~ set rect sel 0 1 2 3 4 5 6 7 samphold~

set tri abs~

pd waves set saw r amp

pd envgen r ampvar $1 20
pd envgen pd envgen pd envgen

pd envgen pd envgen pd envgen pd envgen / 100 line~

*~ 0
noise~
pd envelope expr~ 1 - $v1
samphold~
*~ *~ *~
*~ *~ *~ *~ *~ *~ r stereospread

catch~ rev2 *~ 0

catch~ rev1
*~ 0.25 expr~ ($v1 * 0.5) + 0.5
r gain r feedback
*~

rev3~ 100 90 3000 20 expr~ 1 - $v1 sqrt~


*~ *~
sqrt~

dac~ throw~ rev1 throw~ rev2

Figure 184: La patch finale

14.6 G RANULAZIONE CON SUONI CAMPIONATI

L’ultimo tipo di sintesi granulare prevede l’uso di suoni campionati per la


forma d’onda interna al grano. Come già detto in precedenza infatti, la
forma d’onda interna ad un grano può essere di qualunque tipo e nulla
vieta di usare come sorgente un file audio o il segnale di ingresso di un
microfono.

Come negli altri tipi di implementazione, anche in questo caso le scelte da


fare prima di realizzare l’algoritmo sono molte e riguardano prima di tutto

182
inlet bang
r gdur

f 20

0, 1 $1

vline~

*~ 512 r envform

tabread4~ bell

outlet~ env

Figure 185: La subpatch per la generazione di un treno di grani

la scelta della sorgente e poi la modalità di scansione della stessa. In figura


186 è mostrato uno schema di tali possibilità.

audio source

adc~ audio file

normal manipulated
playback playback

forward
variable
backward
speed
random

Figure 186: Tipi di utilizzo di audio campionato

La sintesi granulare sui campioni permette non solo di generare timbri in-
teressanti, ma anche di processare i campioni stessi per il time stretching
e il pitch shifting. L’argomento richiederebbe uno spazio ben più ampio

183
rispetto a quello che possiamo dedicargli in questo testo, ma nel prossimo
capitolo proporremo alcuni esempi di granulazione applicati a suoni cam-
pionati.

184
15 LAVORARE CON SORGENTI
AUDIO ESTERNE

15.1 S INTESI VS . CAMPIONI

Concettualmente pd lavora nel dominio del suono intervenendo su tutte


le fasi della costruzione e della gestione dell’audio. Fino ad ora ci siamo
occupati di suoni creati dentro pd stesso, abbiamo capito come crearli, ge-
stirli, manipolarli, senza mai uscire dal sistema. Abbiamo imparato ad
usare i generatori di segnale principali (osc∼, phasor∼, noise∼ e altri)
e da quelli abbiamo imparato a crearne di nuovi. Grazie alle tabelle e
a tabosc4∼ etabread4∼ abbiamo acquisito le capacità per creare pratica-
mente qualunque tipo di forma d’onda.

La sintesi audio però è solo una parte di quello che pd ci permette di


fare. Ci sono tutta una serie di oggetti e procedure che permettono di
elaborare sorgenti sonore esterne. L’antica distanza fra suoni di sintesi e
Musique Concrète in pd è definitivamente superata non solo in termini di
convivenza dei due mondi, ma perché il suono campionato può diventare
fonte di produzione di suoni sintetici.

15.2 A LCUNI OGGETTI UTILI

Il primo oggetti che esaminiamo in questa sezione è adc∼, che è l’alter


ego del ben noto dac∼. Quest’ultimo si occupa di convertire il segnale dal
formato numerico a quello analogico, mentre il primo converte il segnale
analogico in segnale numerico in modo che possa essere utilizzato in pd (o
in qualunque altra applicazione digitale). Sostanzialmente adc∼ prende il
suono in entrata della scheda audio e lo campiona al samplerate scelto (tipi-
camente 44100 campioni al secondo) rendendolo disponibile a pd per l’uso.

185
Una volta dentro il segnale può essere trattato come un qualunque seg-
nale numerico. Dopo essere stato processato, elaborato, manipolato o
quant’altro può essere riconvertito tramite dac∼ e rimandato alla scheda
audio.

L’oggetto accetta anche degli argomenti numerici, che definiscono l’indice


delle eventuali entrate. Ad esempio adc∼ 1 2 3 4 5 6 7 8 istanzia un
adc∼ con otto canali in entrata. La stessa cosa può essere fatta con dac∼.
Ovviamente la scheda deve permettere l’entrata e l’uscita del numero di
canali desiderato. Se la scheda permette solo quattro canali, gli altri quat-
tro resteranno inattivi.

La figura 187 mostra una situazione in cui il suono entra in pd con adc∼
ed esce con dac∼ (una patch assolutamente inutile, ma esplicativa).

adc~ adc~ 1 2 3 4 5 6 7 8

dac~ dac~ 1 2 3 4 5 6 7 8

Figure 187: adc∼ e dac∼ in azione

Il secondo oggetto in questione è openpanel, che insieme a soundfiler con-


sente di aprire un file audio e inserirlo in una tabella per essere utilizzato
in vari modi. openpanel alla ricezione di un bang apre una finestra di di-
alogo da cui è possibile scegliere un file situato nell’hardisk del computer.
soundfiler, tramite il messagio read, consente di convertire un file binario in
una lista di numeri in virgola mobile e inserirli in una tabella. Al contrario,
tramite il messaggio write fa esattamente il contrario: converte in binario
il contenuto di una tabella. La figura 188 mostra una patch in cui un file
audio viene messo in un’array. Tramite openpanel si sceglie il file da aprire e
soundfiler lo inseriamo nell’array. L’argomento -resize adatta la dimensione
della tabella tab-file a quella del file stesso. Oltretutto soundfiler emette dal
suo outlet la dimensione in campioni del file importato.

186
openpanel

read -resize $1 tab-file

soundfiler

60480

tab-file

Figure 188: Importazione di un file audio in una tabella

Come sempre i file di help dei due oggetti sono utili per una conoscenza
completa di tutti i messaggi che gli oggetti accettano.

Gli ultimi due oggetti di questa sezione sono readsf∼ e writesf∼. Il


primo consente di aprire un file audio e di eseguirlo, il secondo consente
di registrare il flusso audio di pd in un file audio. La figura 189 esemplifica
l’uso di entrambi. Al contrario di openpanel, savepanel consente di creare un
file su cui si andrà a scrivere. Per utilizzare writesf∼ è necessario ine ffetti
prima creare il file vuoto su cui si scriverà il segnale, poi si può avviare la
registrazione tramite il messaggio start (oppure 1, in alternativa. stop in-
terromperà la scrittura (zero in alternativa). Analogamente readsf∼ avvia
il playback del file con start (1), lo interrompe con stop (zero). Entrambi
gli oggetti accettano alcuni argomenti, il primo dei quali è il numero dei
canali.

15.3 U N SEMPLICE random slicer

Già con la conoscenza di questi pochi oggetti è possibile fare cose interes-
santi con i file audio. In questa sezione implementiamo un random slicer,
cioè un algoritmo che prende un file audio, tipicamente un pattern di batte-

187
openpanel

open $1
start

stop
savepanel

readsf~ 2 open $1

start

stop

writesf~ 2

Figure 189: readsf∼ e writesf∼

ria e lo fa a fette (slice significa fetta per l’appunto) e lo riesegue cambiando


casualmente l’ordine di esecuzione delle fette. È una tecnica molto usata
in certa dance music per rendere meno ripetitivo un pattern ritmico.

Prima di procedere è necessario preparare o procurarsi un file audio che


sia loopabile, cioè che funzioni bene nel momento in cui venga eseguito in
forma circolare, cioè quando giunto al termine ricominci da capo senza
soluzione di continuità. La rete offre gratuitamente tantissimi pattern di
batteria scaricabili gratuitamente 1 .

Tipicamente uno slicer divide il pattern per una potenza di due perché il
sistema ritmico della tradizione occidentale tendenzialmente tende ad es-
sere binario, soprattutto in circostanze di questo tipo. Quindi prima di
tutto implementeremo un sistema per scegliere in quante slices dividere il
pattern.

Come si vede in figura 190 l’oggetto soundfiler restituisce la dimensione in


campioni del file audio. Tale dimensione viene divisa per 44.1 per averne
la dimensione in millisecondi. Questa misura viene divisa per il numero
di slices che si scelgono con la GUI (16 di default) per avere la durata in
millisecondi di una singola fetta. D’altra parte la dimensione in campi-

1 Si veda per sesmpio il sito http://www.freesound.org

188
oni viene divisa per il numero delle fette per avere la dimensione in cam-
pioni di ogni fetta. I due valori ottenuti saranno gli unici necessari per
l’implementazione dell’algoritmo.

inlet bang

openpanel

read -resize $1 drumfile

soundfiler

inlet div

t b
t b b f
f
2

/ 44.1 pow 4

s slicenum
/ 16 / 16

s msdur s sampdur

Figure 190: Scelta del numero di slices

In figura 191 un oggetto metro controlla l’emissione ordinata delle slices.


L’algoritmo non fa altro che riprodurre le fette una alla volta, eseguendo il
file come è in origine.
Ogni fetta è attivata tramite vline∼ che legge la porzione di tabella in-
teressata alla velocità di msdur, cioè alla velocità della durata di una slice.
All’uscita di vline∼ il segnale viene prima moltiplicato per la durata di
una fetta in campioni, poi viene sommato a questo segnale l’offset di let-
tura. Il contatore infatti conta da 0 a 15, cioè le slice da leggere, il risultato
è moltiplicato per la durata della slice in campioni e il tutto viene aggiunto
al segnale di vline∼.

Una volta costruito il motore che gestisce l’esecuzione delle slices al giusto
tempo si può aggiungere la parte di algoritmo che si occupa della scelta
delle fette da eseguire. Nell’esempio precedente infatti la scelta è quella di
eseguire tutte le slice nell’ordine, il che ha poco senso perché si ha una ripe-
tizione pedissequa del pattern sempre uguale. L’intervento più semplice da
fare è quello di sostituire al contatore un oggetto random che scelga casual-

189
choose_division start
r msdur
1
metro
1/2
1/4 t b b
1/8 f + 1
open a file
1/16
bang 1/32 r slicenum
f
% 16
pd slicersettings
0, 1 $1

vline~
r sampdur
*~
drumfile
*
+~ s cursor

tabread4~ drumfile

$1 20

line~
*~

dac~

Figure 191: Slicer che riproduce il pattern in ordine

mente la slice da eseguire. Il risultato sarebbe sicuramente più interessante,


ma si perderebbero i punti di riferimento perché presumibilmente i colpi
accentati e quelli non accentati della batteria sarebbero distribuiti troppo
casualmente.

Un risultato sicuramente migliore è quello di far eseguire le prime 8 slices


in ordine, e di scegliere casualmente fra le restanti 8 quelle da eseguire. La
figura 192 mostra la parte di algoritmo da sostituire per realizzare le due
possibilità appena descritte. Nel secondo caso l’oggetto expr esegue un if
sul numero in entrata: se minore di 8 (quindi tutte le slices da 0 a 7) le fa
uscire così come sono entrate, se maggiore di 8 emette un numero casuale
compreso fra 8 e 15.
In quella porzione di algoritmo si può fare qualunque cosa che renda inter-
essante l’esecuzione attraverso scelte più o meno randomiche. Ad esempio
si può fare in modo che le slices pari restino invariate nell’ordine di ese-

190
start
r msdur
metro
sezione da
sostituire f + 1
t b b
f + 1 ------> r slicenum
------> random 16
% 16
r slicenum
f
% 16 expr if($f1 < 8, $f1, random(8, 16))

0, 1 $1

vline~
r sampdur
*~
*
+~ s cursor

tabread4~ drumfile

$1 20

line~
*~

dac~

Figure 192: Slicer che riproduce il pattern in ordine

cuzione e le dispari siano casuali, oppure si può costruire un dispositivo


che effettua un freezing, cioè che blocca la manipolazione delle slices ripe-
tendo l’esecuzione della slice attiva al momento del freezing stesso. Si può
anche decidere di eseguire alcune slices al contrario, magari scegliendo la
probabilità con cui una fetta venga eseguita in questo modo.

La figura 193 mostra il random slicer con un freezer e con la possibilità di


impostare la probabilità di slices eseguite al contrario.
L’oggetto expr lascia passare le prime 4 fette e le fette dall’ottava all’undicesima
nell’ordine giusto, mentre randomizza tutte le altre. spigot invece gestisce
il freezing filtrando le comunicazioni. Infine random in combinazione con <
e sel gestisce la probabilità di reversing.

15.3.1 CONTROLLARE LO slicer VIA SEGNALE

Implementando il random slicer abbiamo usato un oggetto metro per control-


lare il timing dell’emissione delle slices. Naturalmente la stessa cosa può
essere realizzata controllando il tutto via segnale. Per la verità lo stesso
algoritmo della patch della sezione precedente può essere realizzato con
controllo via segnale. Invece di usare metro come trigger principale può
essere usato phasor∼.

191
choose_division start r msdur
1 prob_reversing
metro freeze! 5
1/2
expr 1 - $i1
1/4 t b b
1/8 spigot 1
open a file
1/16
bang 1/32
random 100 r probrev f + 1
pd slicersettings
expr 100 - $i1 r slicenum
< 90 % 16
sel 1 0
f expr if($f1 < 4 || ($f1 > 7 && $f1 < 12), $f1, random(0, 8))
0 1 1 0

unpack 0 0

pack 0 0 0

$2, $3 $1

vline~
r sampdur
*~
drumfile *
+~ s cursor

tabread4~ drumfile

$1 20

line~
*~

dac~

Figure 193: Il random slicer con freeezer e probabilità di reversing

La frequenza di phasor∼ sarà quella necessaria a compiere una rampa da


0 a 1 nel tempo corrispondente alla durata complessiva del pattern ritmico.
Poi tale rampa dovrà essere manipolata in modo tale da innescare le slices
in base al numero delle stesse. Per questo useremo l’oggetto wrap∼ che
costringe un segnale in entrata a restare nel range [0,1]. L’oggetto, esat-
tamente, restituisce il segnale in entratta sottratto dall’intero immediata-
mente superiore al segnale stesso. La figura 194 mostra un esempio del
suo funzionamento. il segnale generato da un phasor∼ viene moltiplicato
per 4, generando quindi una rampa che va da 0 a 4. wrap∼ compie la sua
operazione generando 4 rampe da 0 a 1.

La prossima figura (195) mostra come si possa leggere una tabella a fram-
menti tramite phasor∼, wrap∼ e samphold∼.

192
phasor~(x)
4,0

3,0

2,0

1,0

0,0

*~ 4
4,0

3,0

2,0

1,0

0,0

wrap~
4,0

3,0

2,0

1,0

0,0

Figure 194: L’oggetto wrap∼

L’algoritmo necessita di qualche spiegazione. Supponiamo di avere una


tabella con un file audio della durata di un secondo esatto, quindi della
lunghezza di 44100 campioni e supponiamo di voler dividere il file in 4
slices. L’oggetto phasor∼ avrà frequenza 1. Ciò significa che in un secondo
genera una rampa che va da 0 a 1. Si moltiplica il segnale per 4 (cioè per
il numero di slices che abbiamo scelto), quindi la rampa generata in un sec-
ondo andrà da 0 a 4. wrap∼ genera quatro rampe da 0 a 1 al tempo totale
di un secondo. Ogni rampa quindi durerà 1/4 di secondo. Il segnale in
uscita viene moltiplicato per la durata di una slice in campioni, cioè 1/4 di
44100 nel nostro caso. Escludendo tutto il resto della patch in questo modo
in un secondo vengono letti 4 volte i primi 11025 campioni della tabella.
Se terminassimo qui il nostro algoritmo e se i primi 11025 campioni della
tabella contenessero il suono della cassa di una batteria si udirebbe un
rullo continuo di questa cassa.

193
phasor~ 1

*~ 4

wrap~

samphold~
*~ 11025
*~ 11025
+~

tabread4~ drum

table drum 44100

Figure 195: Leggere una tabella affettata via segnale

La parte destra della patch invece permette di proseguire nella lettura della
tabella oltre i primi 11025 campioni. L’oggetto samphold∼ campiona il seg-
nale che arriva nell’inlet di sinistra ogni volta che il segnale di destra torna
a zero. Nel nostro caso ogni volta che la rampa generata da wrap∼ torna a
zero il segnale in uscita dal moltiplicatore viene fatto uscire da samphold∼.
In pratica quando wrap∼ genera la prima delle 4 rampe samphold∼ farà
uscire il primo campione della rampa moltiplicata, cioè zero, con la sec-
onda rampa di wrap∼ uscirà 1, con la terza 2 e così via. Usciranno così
in ordine il numero delle slices, che vengono immediatamente moltiplicate
per la durata in campioni. Rappresentano un offset che viene sommato al
primo segnale.

Con questo principio è possibile costruire un random slicer controllato via


segnale. Attraverso expr∼ si possono anche compiere varie operazioni sul
segnale in modo da manipolare la scelta delle fette come nell’algoritmo
della sezione precedente.

Le prossime immagini mostrano un algoritmo simile a quello, con possibità


di freezing, reversing e rolling cioè ripetizione rapidissima di una slice. Per
quest’ultimo caso basta raddoppiare (o quadruplicare) la velocità di lettura

194
ed eseguire per un po’ la stessa fetta. Le immagini seguenti mostrano
l’algoritmo generale (fig. 196), e la varie subpatches (figg. 197,198 e 199).

choose_division

1
1/2
1/4
1/8
choose a file
1/16 r phasordur
bang 1/32
phasor~
pd slicersettings pd roll
sig~ 16
r slicenum
*~
expr~ random(0, 100) expr~ if($v1 < (($f2 / 2) - 1), $v1, random($f2 / 2, $f2))

r freeze

wrap~ expr 1 - $i1


*~
samphold~
rev_prob 10

freeze!
expr~ if($v1 < $f2, -1, 1)
*~ rep_prob 0
r sampdur
*~ expr~ $v1 < 0.5
samphold~
r sampdur edge~
*~ random 100 pd freezerep
drumfile
+~ snapshot~

s cursor expr if($f1 < $f2, 1, 0)

tabread4~ drumfile AMPLITUDE s freeze

$1 20

line~
*~

dac~

Figure 196: Il random slicer controllato da phasor∼

15.4 G RANULAZIONE SU FILES AUDIO

Una volta che un file audio è stato caricato in una tabella può essere ma-
nipolato, come abbiamo visto, in modi diversi. Uno dei comportamenti più
visibili è determinato dal cambiamento della velocità di lettura dei campi-
oni. Aumentare la velocità di lettura comporta un aumento della frequenza
del file e una diminuzione del tempo di esecuzione, viceversa, diminuire la

195
inlet bang

openpanel

read -resize $1 drumfile

soundfiler

inlet div

t b
t b b f
f
2

pow 4
/ 44.1
s slicenum
expr 1000 / $f1 / 16

s phasordur s sampdur

Figure 197: la subpatch che gestisce la scelta del file e il numero delle slices in cui
suddividerlo

r freeze

== 1
r sampdur
+ 1
expr $f2 / $f1

r slicenum

* 16

outlet

Figure 198: La subpatch per impostare la velocità di lettura della tabella

velocità farà diminuire la frequenza e aumentare la durata dell’esecuzione.

Se leggiamo un file di un secondo in mezzo secondo, quindi con un fattore


di moltiplicazione 0.5, dimezzeremo il tempo ti esecuzione e trasporremo
le frequenze esattamente del doppio. La patch in figura 200 mostra un al-
goritmo che permette di cambiare la frequenza del phasor∼ che legge la
tabella. All’aumentare della frequenza si osserva una trasposizione della

196
inlet freeztog inlet repprob

t b
t f f b
f
spigot

* 100

outlet rep

Figure 199: La subpatch per il freezing e il rolling

frequenza del campione.

SPEED(-5/5)
open_file
expr $f1 / 10 - 5
openpanel

r origdur read -resize $1 audiofile


4.7
soundfiler

t b f
phasor~ 1
f
*~
expr 1000 / ($f1 / 44.1)

tabread~ audiofile s origdur

AMPLITUDE
audiofile
sig~

lop~ 1

*~

dac~

Figure 200: Modifica della durata e della frequenza

197
Certamente la cosa più interessante è cercare di svincolare i due compor-
tamenti, cioè rendere indipendente la durata dalla trasposizione. Questo è
possibile farlo, realizzando un algoritmo di tipo granulare, che segmenta il
file audio in piccoli segmenti e su quelli opera una trasposizione, ma allo
stesso tempo lascia invariata la durata del file stesso.

Il principio è semplice: si divide il file in grani, si stabilisce un fattore di


trasposizione e uno di time stretching. Nel caso si voglia allungare la durata
di un file audio i grani verranno eseguiti non proprio uno dietro l’altro, ma
con una certa distanza l’uno dall’altro. Se, in questo caso, si decide di non
trasportare il campione, la frequenza delle altezze rimarrà la stessa, mentre
aumenterà la durata del file. Viceversa si può lasciare invariata la durata
del campione e di trasportare il grano aumentando o diminuendone la ve-
locità di esecuzione. In entrambi i casi però si produrrà un intervallo di
silenzio fra un grano e l’altro.

Quando un grano viene trasposto verso l’acuto si accorcia inevitabilmente


e nel momento in cui la durata totale resta la stessa, al termine del grano
ci sarà una certa quantità di silenzio. Quando invece il grano non viene
traposto, rimane identico all’originale, ma se si rallenta l’esecuzione si pro-
durrà lo stesso fenomeno.

La fig. 201 mostra questo comportamento. La prima immagine mostra


il frammento di file suddiviso in grani di uguale durata ed equidistanti.
Nella seconda immagine i grani, di identica durata rispetto all’immagine
precedente, vengono rarefatti in modo da allargare il tempo di esecuzione
(in questo caso la metà del tempo) mentre nella terza immagine il tempo
rimane uguale all’originale, ma i grani vengono trasposti di un’ottava (fre-
quenza doppia).

L’algoritmo che descriveremo è stato implementato e proposto come tuto-


rial di pd da Miller Pusckette stesso 2 .

La figura 202 mostra l’algoritmo nella sua interezza.


Per semplicità abbiamo diviso la patch in regioni etichettate con lettere
maiuscole per facilitare i riferimenti. La regione A permette di impostare

2 Si tratta della patch-tutorial che si chiama B14.rockafella.sampler.pd che si può trovare nella
cartella doc/3.audio.examples dentro la cartella principale di pd

198
original file

0 200 400 600 800 1000


samples
time stretching

0 200 400 600 800 1000


samples
pitch transposing

0 200 400 600 800 1000


samples

Figure 201: Principio di granulazione di un file audio per time stretching e pitch
shifting indipendenti

la dimensione del grano (chunk size), scelta in millisecondi, ma poi trasfor-


mata in secondi moltiplicando il valore per 0.001. La regione B imposta
la velocità in percentuale del campione da manipolare e la sua lunghezza
(in millisecondi, trasformati in secondi). La regione C invece permette la
trasposizione del campione, in decimi di mezzitoni. Le regioni D1 e D2
infine processano il tutto. Sono due frammenti di codice identici perché
c’è anche un fattore di overlapping di due grani, quindi ci saranno due
treni di grani sovrapposti, al fine di evitare quella frammentazione di cui
si è parlato prima.

199
A

40 <-- chunk size (msec)


C
* 0.001
chunk size 0 <-- transposition, halftones/10
s chunk-size in seconds
r chunk-size r precession
B
t b f t b f
50 <-- precession, percent
* 0.01 loadbang expr (pow(2, $f1/120)-$f3)/$f2

s precession 900 12.5


/ 900 <-- loop length phasor~
(msec)
phasor~ * 0.001 s~ phase +~ 0.5

*~ t b f wrap~

s~ read-pt s~ phase2

D1
D2
r chunk-size

samphold~ r chunk-size
r~ phase
*~ r~ phase samphold~ r~ phase2

+~ r~ read-pt *~ r~ phase2
r~ phase
*~ 44100 +~ r~ read-pt
r~ phase2
-~ 0.5
*~ 44100
+~ 1 -~ 0.5
*~ 0.5
tabread4~ table23 +~ 1 *~ 0.5
cos~
tabread4~ table23 cos~
*~
*~
+~

hip~ 5

output~ choose_a_file
dsp
volume pd table

Figure 202: la patch per il time stretching e il pitch shifting indipendenti

Sulla regione A non c’è nulla da aggiungere. Nella regine B la percentuale


della velocità del campione da leggere (per esempio il 50% significa che il
frammento di file sarà eseguito a velocità dimezzata) viene divisa per la
durata in secondi del campione che si vuoi eseguire. Il risultato diventa la
frequenza di un phasor∼ il cui segnale viene a sua volta moltiplicato per

200
la durata del file da eseguire. In sostanza phasor∼ restituisce una rampa
che va da 0 alla lunghezza del campione da processare con una frequenza
che corrisponde alla velocità a cui vogliamo sia eseguito.

Se volessimo una lunghezza del file da eseguire pari a 900 millisecondi,


cioè 0.9 secondi alla velocità originale (il 100% della velocità), phasor∼
covrebbe compiere 1000/900 rampe al secondo, cioè 1.1111. Nel caso di ve-
locità al 50%, come nel nostro esempio, si dividerà 500 per 900, cioè 0.5555.
Questa è la rampa che va da 0 a 0.9. Come si vede dalla regione D1 (e D2)
è sufficiente moltiplicare tale rampa per 44100 per avere la lettura della
tabella dal primo campione fino al campione 44100*0.9, cioè 39690.

La regione C genera una rampa da aggiungere alla rampa principale. È nec-


essario calcolare la velocità di lettura dei grani che consenta di mantenere
indipendente l’altezza del campione rispetto alla velocità di riproduzione.
Se, ad esempio, decidiamo di eseguire il campione a una velocità del 100%
non ci sarà alcuna granulazione e la regione C attribuirà alla rampa secon-
daria il valore di zero, ma se vogliamo eseguire il campione al 50%, senza
avere trasposizione, i grani dovranno essere eseguiti più velocemente, in
modo da mantenere la frequenza originale.

Oltretutto vengono create due rampe, una con differenza di fase di 0.5, in
modo da creare un overlapping per riempire i vuoti generati soprattutto in
fase di riduzione della velocità.

Le regioni D1 e D2, tramite samphold∼ eseguono la rampa principale (r∼


read-pt) e aggiungono la rampa secondaria, D1 quella con fase zero (r∼
phase), D2 quella con fase 0.5 (r∼ phase2).

201
Part III

APPLICAZIONI VARIE
16 E S T E N D I B I L I TÀ D I P D

16.1 PD COME LINGUAGGIO DI PROGRAMMAZIONE

Come abbiamo già avuto modo di mostrare, Pd è un vero e proprio lin-


guaggio di programmazione. Pur essendo nato per gestire, creare, ma-
nipolare applicazioni audio Pd ha anche le consuete capacità di calcolo di
qualunque linguaggio e anche numerose estensioni che permettono di fare
cose che vanno ben oltre gli scopi per cui fu pensato in origine.

16.1.1 externals E LIBRERIE

La comunità di sviluppatori e artisti che si muove intorno a Pure Data è


molto vasta e ogni giorno vengono annunciate nuove estensioni al software
che ne espandono le potenzialità.

Tali estensioni, tipicamente, consistono in nuovi oggetti che possono o


meno essere raccolti in librerie di oggetti. Nella sezione relativa abbiamo
visto che in Pd c’è la possibilità di incapsulare degli algoritmi dentro le
subpatches, che possono però essere utilizzati solo nel contesto della patch
in cui sono creati. Quando tali algortimi affrontano problemi più generali
e devono quindi essere utilizzati in contesti diversi, possono essere riutiliz-
zati come abstractions. In questo caso si tratterà di normali patch con inlet
e outlet che vengono salvate con estensione pd e poste all’interno del path
per poter essere richiamate ogni qualvolta siano necessarie.

Un terzo tipo di incapsulamento degli algoritmi è quello costituito dagli ex-


ternals che si presentano come normalissimi oggetti pd, ma che non fanno
parte della libreria standard del programma e non possono essere visibili
al loro interno come le normali abstractions perché sono realizzate in lin-
guaggio C e compilate appositamente per l’uso in Pd.

203
Gli externals a volte vengono organizzate in librerie che possono essere
caricate per intero all’apertura del programma. Il menu Startup serve a
localizzare la posizione di tutte le librerie che bisogna caricare all’avvio
del programma.

16.1.2 ALCUNE LIBRERIE

Pd nella sua versione extended include già numerose librerie, che rendono
il programma funzionale a un utilizzo molto esteso. la libreria GEM, che
esamineremo più dettagliatamente nel capitolo successivo, offre una serie
di oggetti per manipolare immagini e video. cyclone mette a disposizione
degli utenti di pd una serie di oggetti-cloni de Mas/Msp, di cui fra l’altro
abbiamo già fatto uso più volte(Uzi, counter, drunk, etc. . . ). La libreria zexy
estende genericamente sia il parco degli oggetti audio che quelli dati. pmpd
è una libreria di oggetti per simulare comportamenti fisici del mondo reale.

per una lista completa delle librerie e delle loro funzionalità rimandiamo
al portale di pure data (http://puredata.info/).

204
17 GEM E IL VIDEO

17.1 LA LIBRERIA GEM

La libreria GEM è una libreria per la gestione del video e delle immagini
in pd.

Si basa sull’uso di alcuni oggetti fondamentali che consentono di creare,


gestire, aprire o chiudere una finestra particolare attivata tramite l’oggetto
gemwin in cui viene effettuato il rendering video. Come mostrato in figura
203 l’oggetto gemwin riceve i messaggi create e destroy per creare e distrug-
gere la finestra grafica e i messaggi 1, per attivare il rendering e 0 per
disattivarlo.

create
destroy

gemwin

Figure 203: Gestione della finstra grafica di GEM

uns volta abilitato il rendering nella finestra grafica, è possibile creare delle
forme all’interno di essa. L’oggetto gemhead abilita il rendering di ogni
tipo di forma e deve essere presente all’inizio di una catena di creazione
della forma. L’oggetto che identifica una forma, ad esempio square per un
quadrato, deve trovarsi alla fine di questa catena. Fra questi due estremi
della catena possono essere presenti molti atri oggetti che gestiscono la
forma: colore, dimensioni, posizione, etc.
Nella figura 204 creiamo prima la finestra di GEM con create, poi attiviamo

205
il rendering con toggle e quindi vedremo apparire un quadrato di colore
bianco (l’argomento dell’oggetto color 1 1 1 scala fra 0 e 1 i valori di RGB,
cioè rosso, verde e blu, tutti impostati al massimo per dare il bianco).

create gemhead
destroy
color 1 1 1

gemwin square

Figure 204: Creazione di un quadrato

L’oggetto color fa parte di quella categoria di oggetti detti manipulators che


consentono di manipolare le forme in vari modi. L’oggetto translateXYZ
consente di spostare nello spazio una forma. Come si intuisce le dimen-
sioni sono tre, quindi lo spazio è tridimensionale. Nella prossima patch
(fig. 205), c’è un quadrato di dimensione 0.25 che si sposta in uno spazio
a due dimensioni (la coordinata Z quindi non ci interessa) ogni quarto di
secondo.

Le coordinate variano da -4 a 4 sia per l’asse delle x che per quella della y,
quindi il punto [0,0] rappresenta il centro del piano.

Le forma possibili,chiamate Geos nella terminologia GEM e identificate da


oggetti con lo stesso nome, sono:

• square

• circle

• triangle

• cube

• sphere

• cone

206
create gemhead
destroy
color 1 1 1 metro 250

gemwin t b b

random 800 random 800

/ 100 / 100

- 4 - 4

translateXYZ

square 0.25

Figure 205: Traslazione di un quadrato

Invece i manipulators sono:

• color

• colorRGB

• rotate

• rotateXYZ

• scale

• scaleXYZ

• translate

• translateXYZ

Come sempre gli help di ognuno di tali oggetti possono essere un va-
lidissimo ausilio per la comprensione del loro comportamento. Il sito in-
ternet http://gem.iem.at/documentation/manual/manual presenta invece
un manuale abbastanza esaustivo sulla libraria GEM.

207
17.2 INTERAZIONE AUDIO E GEM

Già con queste poche nozioni possiamo creare un algoritmo in cui audio
e video interagiscono. Nella patch in figura 206 metro invia un bang ad un
inviluppo d’ampiezza controllato da line∼ per l’oscillatore, ma allo stesso
tempo controlla il colore del quadrato con un inviluppo identico, che va
a modificare il primo dei tre colori dell’oggetto color, che varia dal rosso
(quando è 1) al nero quando è zero.

create
destroy
activate

gemwin
metro 500

delay 50
gemhead

100 25 0 150 osc~ 80 1 25 0 150

line line~

* 0.01
*~

$1 0 0
dac~

color 0 0 0

square 0.25

Figure 206: Esempio di interazione audio/video

Volendo usare più oscillatori e più quadrati no dovremmo fare altro che
copiare la aprte di patch che ci interessa e aggiungere un oggetti transla-
teXYZ per sistemare opportunamente i quadrati nello spazio.

la prossima patch è un po’ più elaborata (fig. 207. Un oggetto metro emette
bang ogni 125 o 250 millisecondi. random genera un numero compreso fra

208
0 e 6 inviandolo a sel che smista i bang di uscita fra varie combinazioni: gli
oscillatori possono suonare tutti insieme, due alla volta oppure uno alla
volta, in base al numero generato da random.

La subpatch di sinistra (quadsx) invia il segnale a sinistra nel campo stereo


e in minor quantità a destra, viceversa quella di destra. Il segnale della
subpatch centrale è in posizione centrale.

La patch di sinistra e quella di destra possono anche ricevere frequenza di-


verse e in base a quelle il quadrato si sposterà sull’asse verticale (y) mentre
l’oscillatore centrale suonerà sempre la stessa frequenza, lasciando il suo
quadrato nella stessa posizione.

la figura 208 mostra l’interno della subpatch quadsx. Il bang ricevuto dall’inlet
attiva l’inviluppo di ampiezza del generatore dell’onda (in questo caso un
phasor∼) e la produzione del colore. Allo stesso tempo mette in azione
un oggetto random che genera numeri compreso fra 0 e 2, che andranno
a modificare la posizione del quadrato sull’asse delle y e la frequenza del
generatore audio, che varierà fra i valori 500, 1000 e 1500.

La subpatch quaddx è identica, con l’unica differenza che l’oggetto transla-


teXYZ ha come argomento 2 invece di -2, quindi sarà traslata un a destra
rispetto al centro.

la subpatch quadc, del quadrato centrale (fig. 209), è più semplice. manca
infatti tutta la gestione della frequenza di osc∼, che ha frequenza fissa (100
hz).

209
create activate
destroy

metro 250 expr (random(1, 3) * 125)


gemwin

random 7

sel 0 1 2 3 4 5 6

$1 5

line~
pd quadsx pd quadc pd quaddx

*~ *~ *~

*~ 0.25
*~ 0.25

dac~

Figure 207: interazione audio video con tre oscillatori e tre quadrati

210
inlet

random 3 delay 100

+ 1
gemhead
* 500
100 5 0 10
phasor~ 1000 1 5 0 10

line

* 0.01 - 1 line~

$1 $1 $1 * 2

color 0 0 0 *~

outlet~
translateXYZ -2 0 0

square 0.25

Figure 208: la subpatch del quadrato sinistro (quadsx)

211
inlet

delay 100

gemhead

100 5 0 10 osc~ 100 1 5 0 10

line line~

* 0.01
*~
$1 0 0
outlet~

color 0 0 0

translateXYZ 0 0 0

square 0.25

Figure 209: la subpatch del quadrato centrale (quadc)

212
18 NETWORKING

18.1 A RCHITETTURA DI RETE IN P D

Il concetto di Networking assume in pd sfaccettature diverse e complesse.


Semplificando molto si può affermare che l’architettura del sistema sia già
di per sé basata sul modello di comunicazione client-server, laddove un
sistema di messaggistica interna (internal messaging system), basato su un
protocollo di comunicazione detto FUDI, consente di inviare messaggi fra
patch e verso il server.

Tale sistema di messaggistica incorpora due tipi di messaggi, quelli indi-


rizzati al processo che gestisce l’intero sistema compreso il motore audio
(pd messages) e quelli che viaggiano da patch a patch, anche nel caso di patch
prive di interfaccia grafica.

In effetti pd può funzionare, quindi produrre audio, ricevere e inviare mes-


saggi, anche in assenza dell’interfaccia grafica consueta. Questo implica la
possibilità di creare e gestire interfacce implementate in altri linguaggi 1 .
Questo non significa che pd possa comunque fare a meno delle patch, ma
solo che possa nasconderne la visuale grafica all’utente. La patch infatti
non è altro un file di teso in cui compaiono i comandi attraverso i quali si
creano gli oggetti e tutte le altre istanze di un algoritmo.

Una patch si concretizza in quella che in pd si chiama canvas, cioè il con-


tenitore dove gli oggetti, i messaggi e tutto il resto vengono creati e posti
per far si che un algoritmo prenda vita. Solo dalla canvas è possibile dire al
motore audio cosa fare esattamente. Sulla macchina in cui risiede il motore
audio (il pd process) ci dovrà essere necessariamente una patch con relativa
canvas, che avrà il compito di contenere gli oggetti audio e di spedire mes-

1 http://jeraman.info/2009/03/22/how-to-use-pure-data-as-a-api/

213
saggi al motore.

Per semplificare: gli oggetti audio dovranno necessariamente risiedere


nella canvas vicina al server. Tutte le altre macchine remote potranno solo
inviare messaggi alla patch principale, che per semplificare chiameremo
proxy patch, che si occupera di far funzionare tutto. le macchine remote
però potranno costruire e distruggere oggetti dalla loro postazione.

In figura 210 viene mostrato il modello di comunicazione attraverso cui pd


funziona.

client patch client patch

proxy patch

pd engine

Figure 210: Il modello di comunicazione di pd

18.1.1 netsend E netreceive

Proviamo ad esemplificare quanto detto sopra. In concreto dovremo aprire


il pd-engine e una patch che funzioneranno da server e attivare delle client
patch altrove (nel nostro caso tutto avverrà sulla stessa macchina, ma è la
stessa cosa).

214
Nella client patch avremo un oggetto che si occuperà di connettersi alla
proxy patch per inviarle dei messaggi. Tale oggetto è netsend. D’altra parte,
la proxy patch conterrà l’oggetto netreceive che aprirà la porta di una connes-
sione socket e si metterà ina ttesa dei messaggi. A sua volta la proxy patch
potrà inviare messaggi al pd engine tramite normali messaggi preceduti dal
punto e virgola e dalla dicitura pd. In figura 211 abbiamo schematizzato
questo comportamento.

client patch netsend

netreceive
proxy patch
; pd

pd engine

Figure 211: Il modello di comunicazione di pd in dettaglio

Realizzando il tutto in pd ci toroviamo di fronte alla client patch rappresen-


tata in figura 212 e alla proxy patch in figura 213.
L’oggetto netsend necessita di una message box per la connessione (in questo
caso si connette a localhost sulla porta 5555). Una volta stabilita la connes-
sione invierà qualunque tipo di messaggio compatibile con pd, preceden-
dolo dalla parola chiave send. In questo caso potrà inviare due tipi di
messaggio: un numero per la frequenza di un oscillatore e un altro nu-
mero (che sarà zero o 1) per attivare o disattivare l’audio.

215
connect to port 5555
connect localhost 5555

send_osc_frquency
440

send frq $1

active_audio_engine

send active $1

netsend

Figure 212: la client patch che si occupa di inviare messaggi al proxy

netreceive 5555 receive message from


client

route frq active

osc~ 200
active audio
*~ 0.5 to pd engine

;
dac~ pd dsp $1

Figure 213: la proxy patch che si occupa di ricevere messaggi dalla client patch e di
inviare comandi al pd engine

I messaggi saranno precedute da parole-selettori (frq e active, in modo che


il proxy possa smistarli tramite l’oggetto route.

216
La proxy patch è in ascolto sulla porta 5555 con l’oggetto netreceive. L’oggetto
route smista i messaggi. Nel caso riceva un messaggio preceduto dalla
parola-selettore active invierà il numero ricevuto alla message box che si oc-
cupa di spedire il comando di accensione dell’audio al pd engine, comando
che deve essere preceduto dal punto e virgola.

18.1.2 Dynamic patching

Nell’ipotesi di controllare pd da una macchina remota, abbiamo visto che


per ora è possibile, di fatto, inviare da remoto dati numerici ad una proxy
patch che risiede nella stessa macchina del pd engine. In questo modo la
proxy patch riceve solo dati di controllo su una serie di oggetti che costitu-
iscono un algoritmo preconfezionato.

Questa limitazione impedirebbe quindi di programmare gli algoritmi in


tempo reale su un unico motore audio. Allo stato attuale la cosa non è
impossibile, anche se non è agevole come in un linguaggio come SuperCol-
lider 2 dove l’architettura client-server è basata sul protocollo OSC e non
necessita di alcun proxy intermediario fra il client e il server audio.

Negli ultimi tempi la pratica del Live Coding sta prendendo sempre più
piede nell’ambiente dei programmatori dell’audio e anche nella comunità
di pd stanno anscendo applicazioni che rendono possibile il Live Coding
condiviso, cioè la creazione di un’unica patch da postazioni diverse.

Tutte le implementazioni si basano sullo sfruttamento dei patch messages, di


cui abbiamo parlato prima. Attraverso questi particolari internal messages
è possibile creare, distruggere, manipolare oggetti residenti in altre patch,
anche remote.

Ogni internal patch message è costituito da una parola chiave che rappre-
senta l’oggetto da creare o l’azione da compiere, seguita da altri argomenti.
Ad esempio il messaggio:

obj 100 100 osc~ 200

2 http://supercollider.sourceforge.net/

217
crea un oggetto osc∼ in posizione [100,100] della canvas con argomento
200 per la frequenza. Nella figura 214 mostriamo un esempio di questa
procedura.

obj 100 200 osc~ 200

obj 100 250 dac~

floatatom 100 150 5

connect 6 0 7 0, connect 6 0 7 1

connect 8 0 6 0

send pd-internalmessage01.pd

Figure 214: una patch per l’invio di internal messages all’interno della stessa patch

L’oggetto send invia i messaggi alla patch in cui si trova, in questo caso
internalmessage01.pd. Il nome della patch di destinazione deve essere pre-
ceduta dal prefisso pd-. I due messaggi con parola chiave obj creano gli
oggetti osc∼ e dac∼ alle coordinate indicate. Il messaggio floatnum crea
una number box e i tre messaggi connect (i primi due si trovano all’interno
della stessa message box, separati da una virgola, connettono gli oggetti fra
loro.

Cosa significano i numeri che seguono i messaggi di connect? Si tratta di


quadruple di valori che identificano il numero dell’oggetto e l’inlet o l’outlet
da connettere. Il numero dell’oggetto viene attribuito allo stesso nel mo-
mento in cui viene creato, secondo l’ordine di creazione. Questo significa
che, visto che nella patch prima della creazione dei tre oggetti ci sono già
altri sei oggetti, che vengono numerati virtualmente da zero a 5, i nuovi
oggetti saranno numerati a partire da 6, secondo il loro ordine. osc∼ sarà
l’oggetto numero 6, dac∼ il 7, infine la number box l’8.

Il secondo e il quarto numero della quadrupla rappresentano, rispettiva-


mente l’outlet e l’inlet da connettere. Ad esempio il messaggio:

connect 8 0 6 0

218
connette il primo outlet dell’oggetto 8, cioè la number box con il primo inlet
di osc∼, che è l’oggetto numero 6. La figura 215 chiarifica il tutto.

obj 100 200 osc~ 200

obj 100 250 dac~

floatatom 100 150 5

connect 6 0 7 0, connect 6 0 7 1

connect 8 0 6 0

send pd-internalmessage01.pd

0 ---> 8
out 0

in 0
osc~ 200 ---> 6
out 0

in 0 in 1
dac~ ---> 7

Figure 215: La numerazione degli oggetti e degli inlet-outlet all’interno della


stessa patch

Per far si che la numerazione degli oggetti creati inizi da zero è sufficiente
creare nella patch principale una subpatch vuota in cui risiederanno i nuovi
oggetti.

Con lo stesso principio possiamo inviare dei messaggi per creare degli
oggetti da una postazione remota facendo uso degli oggetti netsend e ne-
treceive e con opportuno routing di tali messaggi (tramite route). Le figure
216 e 217 illustrano questo procedimento alla fine del quale la subpatch ob-
jecthost si configurerà come nella figura 218.

219
connect to port 5555
connect localhost 5555

send create vis 1, send create editmode 1

send create obj 20 20 osc~ 200

send create obj 20 50 *~ 0.5

send create obj 20 80 dac~

send create connect 0 0 1 0

send create connect 1 0 2 0

send create connect 1 0 2 1

active_audio_engine

send active $1

netsend

Figure 216: la client patch per l’invio dei messaggi che creano gli oggetti

18.1.3 pdsend

pd dispone di due programmi standalone per la gestione di ciò che abbi-


amo appena esaminato. Si tratta di pdsend e pdreceive che possono essere
eseguiti da linea di comando e fanno le veci di netsend e netreceive.

Questi due programmi consentono di creare delle interfacce con altri lin-
guaggi di programmazione, il che potrebbe essere utilissimo se si riesce
a creare un codice in grado di gestire la creazione di messaggi da una
postazione remota.

Senza entrare troppo nel dettaglio, proviamo a illustrare un esempio di


uso di pd send. in questo caso faremo un uso ibrido dei comandi, ossia
utilizzeremo pdsend per inviare i messaggi e netreceive dentro una proxy

220
netreceive 5555 receive message from
client

route create active

active audio
to pd engine
send pd-objecthost ;
pd dsp $1
pd objecthost

Figure 217: La proxy patch che contiene la subpatch objecthost in cui compariranno
i nuovi oggetti

osc~ 200

*~ 0.5

dac~

Figure 218: la subpatch objecthost con gli oggetti appena creati

patch per ricevere ed eseguire i comandi. La fig. ??) mostra la proxy patch.
Si tratta semplicemente di una canvas che contiene l’oggetto netreceive in
ascolto sulla porta 3001 e con l’argomento zero, che significa che riceverà
messaggi TCP (che sono più affidabili degli UDP, indicati con l’argomento
1). L’ulteriore argomento old è necessario per ricevere qualunque tipo di
messaggio da pdsend.

Prima di tutto è necessario aprire pd, poi la proxy patch, infine aprire una
finestra di terminale. Da lì è necessario navigare fino alla posizione del

221
programma pdsend ed eseguirlo in questo modo:

./pdsend 3001 localhost

oppure

pdsend.exe 3001 localhost

se si è su windows. Poi eseguiamo i seguenti comandi, uno alla volta ter-


minandoli ognuno con il punto e virgola:

pd filename n ./; //crea un nuovo file di nome n


#N canvas; //crea la canvas
#X pop 1; //la apre
pd-n obj 100 100 osc~ 200; //crea un oscillatore con
frequenza 200
pd-n obj 100 150 dac~; //crea un’uscita
pd-n connect 0 0 1 0; //connette i due oggetti
pd dsp 1; //attiva l’audio

Si potrebbe anche aprire pd da terminale senza la GUI, con la linea di co-


mando (supponiamo di aver salvato la patch con netreceive nel file proxy.pd):

./pd -nogui proxy.pd

a questo punto pd è un programma senza interfaccia grafica, completa-


mente gestito da linea di comando. Naturalmente scrivere i messaggi uno
alla volta e con la dicitura completa non è molto comodo, ma ci sono già al-
cune implementazioni reperibili in rete che rendono il tutto estremamente
intuitivo e immediato. La maggior parte fanno uso di Python, ma non man-
cano applicazioni in Perl, Lisp, Scheme, e altri, e c’è da scommettere che
nell’immediato futuro l’uso di pd come motore audio pilotato da interfacce
diverse sarà all’ordine del giorno!

222
18.2 IL PROTOCOLLO OSC

Nato intorno al 1997, OSC è un protocollo che consente la comunicazione


fra computer collegati in rete. I messaggi vengono impacchettati secondo
certi criteri e trasportati tramite i consueti protocolli di trasporto, tipica-
mente UDP, ma anche OSC.

Generalmente i messaggi OSC possono essere di qualunque tipo e si usa


farli precedere da prefissi che rendono semplice il routing nella macchina
ricevente. Tali prefissi hanno la struttura degli indirizzi web, sono prece-
duti cioè da una ’/’ (slash).

Il protocollo OSC è molto utile quando si vuole far comunicare pd con un


software diverso, sulla stessa macchina o verso altre macchine. La comu-
nicazione fra pd e pd è implementata benissimo con gli oggetti netsend e
netreceive quindi non avrebbe molto senso usare OSC, anche se gli esempi
che seguono rimangono nel contesto di pd sia in ricezione che in invio.

In pd le implementazioni del protocollo OSC sono numerose, ma quella


migliore, e forse la più utilizzata in questo momento, è quella costituita
dalla libreria mrpeach. Nonostante questo pd-extended, pur contenendo
tale libreria, non la carica di default all’avvio del programma. Quindi è
necessario caricarla nella tramite il messaggio import.
Gli oggetti necessari a stabilire una connessione OSC e a ricevere/inviare
i messaggi sono udpsend, udp receive, packOSC e unpackOSC. I primi due
servono a stabilire la connessione e a inviare i paccheti, gli altri due a
prepararli per essere spediti, formattano cioè i dati nel formato interno del
protocollo. Nella figura 219 viene mostrato un semplice esempio di comu-
nicazione via OSC.

La macchina che spedisce i messaggi (sender) usa udpsend, si connette alla


porta 3001 dell’indirizzo dell’interfaccia di loopback, cioè localhost perché
si tratta di comunicare nello stesso computer. Infine impacchetta i mes-
saggi, facendoli precedere dalla parola chiave send, tramite packOSC e li
spedisce tramite udpsend.

Il destinatario (receiver) riceve i messaggi tramite udpreceiver, li interpreta


e li spacchetta grazie a unpackOSC, infine li invia a route che li indirizza

223
import mrpeach

connect localhost 3001 udpreceive 3001

0 unpackOSC

send /test $1
route /test

packOSC
0
udpsend

sender receiver

Figure 219: Una semplice connessione OSC

opportunamente.

Il meccanismo di indirizzamento tramite le slash può essere molto elabo-


rato, si tratta semplicemente di organizzare l’indirizzamento per route in
modo da instradare i messaggi in modo coerente.

La figura 220 mostra un esempio di istradamento più elaborato.

Naturalmente nulla impedisce di creare connessioni duplex, dove una macchina


invia e riceve messaggi allo stesso tempo. È sufficiente creare due oggetti
udpsend e udpreceive, ovviamente su porte diverse. in pratica si creano
due connessioni OSC diverse, una per ricevere, l’altra per inviare dati.
Nell’esempio di figura 221 la macchina A invia dati sulla porta 3001 e
riceve sulla porta 3002, la macchina B, viceversa, invia sulla 3002 e riceve
sulla 3001.

Tutte le comunicazioni che abbiamo realizzato nei precedenti esemi fanno


uso del protocollo UDP per trasportare i dati, ma nulla vieta di utilizzare il
protocollo TCP, che è più affidabile anche se a volte meno veloce. Se si usa
una connessione internet per comunicare con pd probabilmente potrebbe
essere meglio usare il TCP, ma in una LAN locale è preferibile in generale

224
import mrpeach

connect localhost 3001 udpreceive 3001

unpackOSC
0
route /data /audio
send /data /sliderA $1

0 route /frq /amp

send /data /sliderB $1


0 0
0
route /sliderA /sliderB
send /audio /frq $1

send /audio /amp $1

packOSC

udpsend
sender receiver

Figure 220: Routing elaborato dei messaggi

utilizzare il protocollo UDP.

Per realizzare connessioni che facciano uso di TCP è sufficiente usare gli
oggetti tcpsend e tcpreceive al posto di udpsend e udpreceive.

18.3 L’ AUDIO IN streaming

I protocolli che abbiamo esaminato fino ad ora (MIDI, OSC, FUDI) trasportano
fondamentalmente dati numerici, simboli, liste, ma non consentono di in-
viare e ricevere campioni audio. Per fare questo occorre utilizzare proto-
colli diversi, implementati in pd da oggetti specifici.

La prima coppia di oggetti che esaminiamo è streamin∼ e streamout∼


che servono a inviare segnale audio fra pd e pd in una LAN o attraverso
una connessione internet.

225
import mrpeach

connect localhost 3001 connect localhost 3002

30 0

send /data $1 send /audio $1

packOSC packOSC

udpsend udpsend

udpreceive 3002 udpreceive 3001

unpackOSC unpackOSC

route /audio route /data

0 0

A B

Figure 221: Connessione OSC duplex

Sostanzialmente sono l’omologo audio di netsend e netreceive, con alcune


differenze che vedremo fra poco. Anche in questo caso è necessario sta-
bilire una connessione tramite la definizione di un indirizzo e di una porta
di comunicazione (fig. 222).
Come appena detto, ci sono delle differenze con netsend e receive, infatti
streamin∼ può accettare un solo segnale per porta, quindi nel caso si vo-
lesse usare tale oggetto come server audio per più client o per un client con
un segnale stereo, ogni segnale dovrebbe essere instradato su una porta dif-
ferente e per ogni porta ci dovrebbe essere un oggetto streamin∼ diverso
(fig. 223).

Per ovviare a questa complicazione è in fase di testing una coppia di


oggetti, netsend∼ e netreceive∼ che consentono di inviare e ricevere seg-

226
connect localhost 3001 streamin~ 3001

osc~ 200
dac~

streamout~

client server

Figure 222: Connessione audio con streamin∼ e streamout∼

nali multicanale su una stessa porta 3 .

Un’altra possibilità notevole che pd offre, è quella di inviare il flusso audio


direttamente ad un server per il media streaming, tramite un protocollo di
tipo multicast. In pratica pd può andare in diretta radio!.

L’oggetto mp3cast∼ svolge questa funzione. Naturalmente bisogna essere


in possesso dell’account e dell’indirizzo di un server streaming, stabilire un
mountpoint, cioè un file temporaneo che funziona come un buffer per mem-
orizzare il segnale e infine è necessario dire all’oggetto che tipo di server
si utilizza (fig. 224).

Come si può notare è possibile inviare un segnale stereofonico. Il segnale


viene compresso nel formato mp3 e inviato in tempo quasi-reale (il ritardo
può essere di circa 10 secondi. A questo punto non è difficile implementare
una semplicissima postazione radio (fig. 225).
La patch è semplice: subpatch che si occupa della connessione (fig. 226),
una che si occupa di inviare tre segnali a mp3cast∼, cioè il microfono, una
mini implementazione di modulazione di frequenza e un oggetto sfplay che
legge file audio per una eventuale esecuzione di playlist (fig. 227). Infine
la subpatch che si occupa dei controller pilotati via MIDI tramite l’oggetto
ctlnin (fig. 228). Va ricordato che le GUI possono ricevere e inviare mes-
saggi tramite send e receive semplicemente impostando il destinatario e il
mittente dalle properties della GUI stessa (fig. 229).
Esiste un altro oggetto che implementa le connessioni a tali tipi di server, si
chiama oggcast∼, che differisce da mp3cast∼, come si intuisce dal nome,
3 http://www.nullmedium.de/dev/netsend~/

227
connect localhost 3001 streamin~ 3001

osc~ 200
streamin~ 3002

streamout~
streamin~ 3003
client A
*~ 0.25
*~ 0.25
streamin~ 3004
connect localhost 3002
*~ 0.25
osc~ 300

dac~
streamout~

client B server

connect localhost 3003 connect localhost 3004

osc~ 600 osc~ 1200

streamout~ streamout~

client C (stereo)

Figure 223: Connessione audio multiple

per il fatto di comprimere l’audio non in mp3 ma in formato Ogg Vorbis.

228
passwd mypass

connect shoutcast.host.com 8000

mountpoint mymusic.mp3

shoutcast osc~ 200

mp3cast~

Figure 224: Trasmettere il proprio segnale in una webradio

bang_to_connect!

mysound playlist

Carrier
109
choose_a_file_to_play
Modulating
70 start/stop

mic mysound playlist

Figure 225: Una semplice postazione radio

229
bang_to_connect!

t b b b b

passwd mypass

connect shoutcast.host.com 8000

mountpoint mymusic.mp3

shoutcast

outlet

Figure 226: la subpatch per la connessione al server multicast

mysound playlist

Carrier
109
choose_a_file_to_play
Modulating
70 start/stop

osc~ 100
osc~ 400
*~ 0.5

+~ 0.5

adc~ r mic *~
sel 1 0 openpanel

$1 20 r mysound prepend open


start stop
line~ $1 20 loadbang

open astronomydomine.wav l
line~
*~ *~
*~
sfplay 2 r playlist

$1 20

line~

inlet messages

*~ *~

mp3cast~

Figure 227: Implementazione dei segnali da inviare alla radio

230
mic mysound playlist

ctlin 1 ctlin 2 ctlin 3

/ 128 / 128 / 128

send sld1 send sld2 send sld3

Figure 228: Configurazione dei controller da pilotare via MIDI

231
Figure 229: la finestra delle properties della vertical slider dove impostare send e
receive

232
19 A P P L I C A Z I O N I S PA R S E

19.1 L APTOP O RCHESTRA

Come si avrà avuto modo di intuire, le potenzialità di pd in merito al


networking sono moltissime. L’idea quindi di organizzare gruppi che suo-
nano su un palco facendo uso di questo programma è molto concreta. La
CLOrk, Concordia Laptop Orchestra 1 , ha sviluppato con pd un sistema
di sincronizzazione dei dati all’interno di una Lan. Pd è usato anche dalla
Linux laptop orchestra 2 e da molte altre.

Quando si tratta di mettere in piedi un’orchestra di laptop le problematiche


sono molte: Ognuno suona un proprio strumento sul suo motore audio o
ci si serve di un motore audio comune? Si improvvisa o si eseguono brani
strutturati? Si suona stereo o in multifonia? Questi problemi naturalmente
possono essere affrontati in base alle condizioni di ogni orchestra.

Il modo più semplice, ma meno orchestrale, è quello di suonare sul proprio


laptop in modo indipendente. Ogni postazione ha in attivo la propria patch
sul proprio motore audio. La figura 230 mostra questa configurazione, che
definiamo di tipo PUNCTUAL.

Nel capitolo sul Networking abbiamo illustrato molte delle funzionalità di


rete offerte da pd. Reamite gli oggetti netsend e netreceive strutturare una
rete di postazioni in cui gira pd è estremamente facile. Una configurazione
possibile è quella in cui il motore audio e la patch principale sono avviati
in un server con l’oggetto netreceive. I client inviano dati al server. Ognuno
si occupa di pilotare parti specifiche della server patch. La comunicazione

1 http://music.concordia.ca/news-and-events/events/dance-music-laptop-orchestra.
php
2 http://l2ork.music.vt.edu/main/

233
PUNCTUAL Architecture

LAPTOP 1 LAPTOP 4
AUDIO ENGINE AUDIO ENGINE

LAPTOP 2 LAPTOP 5
AUDIO ENGINE AUDIO ENGINE

LAPTOP 3 LAPTOP 6
AUDIO ENGINE AUDIO ENGINE

Figure 230: Architettura con postazioni indipendenti

quindi avviene solo dai client verso il server (fig. 231).

Audio centralized

CLIENT 1
Data control part A
netsend 3001 /A

CLIENT 2
Data control part B
netsend 3001 /B
SERVER
netreceive 3001
CLIENT 3
route /A /B /C /D
Data control part C
part A part B part C part D
netsend 3001 /C
AUDIO ENGINE

CLIENT 4
Data control part D
netsend 3001 /D

Figure 231: Architettura con un server che riceve dati di controllo per il motore
audio

Al contrario, in una tipica architettura UNICAST, un server può generare


degli eventi di controllo e inviarli ai client: Si tratta di una sorta di diret-

234
tore d’orchestra che dice ad ogni client quello che deve fare. In questo caso
l’audio è decentralizzato, ogni client ha il proprio motore, incluso il server
(fig. 232).

UNICAST Architecture
(Audio decentralized)

CLIENT 1
netreceive 3000
AUDIO ENGINE

SERVER CLIENT 2
Event Generator
netreceive 3001
netsend 192.168.0.2 3000
AUDIO ENGINE
netsend 192.168.0.3 3001
netsend 192.168.0.4 3002
CLIENT 3
netsend 192.168.0.5 3003
netreceive 3002
localhost
AUDIO ENGINE
AUDIO ENGINE

CLIENT 4
netreceive 3003
AUDIO ENGINE

Figure 232: Architettura UNICAST, il server genera gli eventi-partitura che ven-
gono selettivamente inviati ai client

Un ultimo tipo di proposta è quella che si può definire BROADCAST Ar-


chitecture con audio centralizzato. Un server invia un messaggio comune
(BROADCAST) a tutta la rete, tipo un messaggio di sincronizzazione (clock)
e riceve a sua volta da tutti i client i dati per il controllo del motore audio
(fig. 233). È l’architettura più complessa, poiché richiede una connessione
full-duplex, cioè con doppia direzionalità. la trasmissione viaggia dal client
al server e viceversa.

Naturalmente queste architetture proposte sono legate alle condizioni in


cui si opera, ma sono anche funzionali al concetto di localizzazione della
sorgente sonora. Un’architettura audio centralized accentra l’audio su una
postazione specifica, di conseguenza non permette realmente di associare
il gesto di chi suona a ciò che si ascolta. D’altro canto è più semplice
da gestire dal punto di vista dell’hardware, è sufficiente un impianto di
amplificazione con stereofonia. Molto più complessa è la condizione di

235
BROADCAST FULL-DUPLEX Architecture
(Audio centralized)

CLIENT 1
netreceive
3001
(clock)
netsend
3000
(audio control data)

CLIENT 2
netreceive
3001
(clock)
netsend SERVER
3000
netreceive
(audio control data)
3000
(audio control data)
CLIENT 3 netsend
netreceive 3001(broadcast)
3001 (clock)
(clock) AUDIO ENGINE
netsend
3000
(audio control data)

CLIENT 4
netreceive
3001
(clock)
netsend
3000
(audio control data)

Figure 233: Architettura BROADCAST FULL-DUPLEX, il server invia un clock e


riceve i controlli del motore audio

audio decentralized, dove ogni laptop produce il suo segnale. È ipotizz-


abile un’uscita su canali multipli anche in termini di amplificazione. La
soluzione della PLork (Princeton laptop Orchestra 3 ) è degna di citazione:
si tratta di un’architettura audio decentralized dove ogni componente esce
con il proprio segnale e lo diffonde con uno speaker a irradiamento circo-
lare.

le soluzioni possibili sono tante quante le problematiche, ma le prospettive


di questo modo di suonare sono interessanti e in un futuro molto prossimo
3 http://plork.cs.princeton.edu/

236
le Laptop Orchestra si moltiplicheranno a dismisura.

19.2 I L L IVE C ODING

Una delle direzioni più recenti intraprese nell’ambito della musica elettron-
ica è quella del Live coding, o della programmazione in tempo reale (On the
fly programming o Just in time Programming).

Il principio su cui si basa il Live coding è quello per cui lo strumento (quindi
il suono) e la composizione vengono creati contemporaneamente in tempo
reale dal musicista, che si occupa di scrivere il codice pensandolo nel mo-
mento stesso della messa in atto. Il processo di creazione/composizione
diventa trasparente e accessibile a chi ascolta. Per agevolare questa com-
prensibilità spesso i Live coders si servono di proiettori per divulgare le
immagini del codice creato, commentandolo opportunamente durante il
processo.

Le implicazioni di questa tecnica, di questo modo di procedere, sono moltissime,


soprattutto perché propone un approccio diverso non solo dal punto di
vista del musicista, ma anche da quello dell’ ascoltatore che assume un
ruolo inevitabilmente più consapevole, dal momento che viene diretta-
mente accompagnato alla condivisione di quello che viene creato.

Un software storico come il già citato SuperCollider ha una libreria di Classi


di oggetti (JITlib) che consentono di programmare in tempo reale. Chuck
4 invece è stato pensato proprio per questo, è fortemente orientato alla

programmazione in tempo reale. Sono entrambi ambienti testuali, anche


se hanno la possibilità di generare oggetti grafici.
Impromptu è un’ambiente di programmazione con una spiccata predispo-
sizione al live programming 5 . È un ambiente basato sul linguaggio Scheme,
un dialetto del Lisp, un linguaggio funzionale molto usato negli studi sull’Intelligenza
Artificiale. È un linguaggio elegante ed estremamente espressivo, tanto da
somigliare in certi casi al linguaggio umano.

4 http://chuck.cs.princeton.edu/
5 http://impromptu.moso.com.au/

237
Pd può essere annoverato fra i software più adatti per il Live coding per
alcune ragioni:

• la sua vocazione grafica Dataflow consente di capire esattamente come


viene creato un algoritmo. Gli oggetti vengono collegati in modo
logico attraverso cavi di collegamento, dando un’idea molto precisa
dei rapporti di causa-effetto fra gli eventi;

• gli oggetti grafici GUI, che tendono a nascondere i processi, sono


relativamente limitati e se ne può evitare l’uso molto agevolmente;

• a differenza di Max, suo fratello maggiore, non crea problemi di click-


ing audio quando si stacca un cavo o se ne crea uno.

Pd per adesso non ha librerie specifiche per il Live coding, anche perché
non ne ha bisogno. Di fatto usare pd significa programmare sempre in
tempo reale! Naturalmente questo non significa che tutti i programmatori
di pd siano dei buoni live coders. Si tratta infatti di acquisire una certa
dimestichezza con l’immaginare algoritmi in tempi rapidi e di realizzarli
senza troppi errori.

La disciplina è in continua espansione e il sito toplap.org, il centro nevral-


gico del Live coding, propone anche degli esercizi per imparare a realizzare
algoritmi in modo chiaro e rapido. La soluzione agli esercizi è quasi sem-
pre scritta in codice per SuperCollider, ma nessuno impedisce di provare a
risolverli in pd!

19.3 A RDUINO

238
CONCLUSIONE

239
BIBLIOGRAFIA

AA.VV. [2000], The CSound Book, ed. by R. Boulanger, The MIT Press, Cam-
bridge.
– [2010b], The Audio programming Book, ed. by R. Boulanger and V. Laz-
zarini, The MIT Press, Cambridge.
– [2011], The SuperCollider Book, ed. by S. Wilson, D. Cottle, and Collins N.,
The MIT Press, Cambridge.
Bianchini, Riccardo and Alessandro Cipriani [1998], Il suono virtuale. Sintesi
ed elaborazione del suono. Teoria e pratica con Csound. Con CD-ROM, Con-
TempoNet.
Blum, Frank [2007], Digital Interactive Installations: Programming interactive
installations using the software package Max/MSP/Jitter, VDM Verlag Dr.
Mueller e.K., Cambridge.
Collins, Nick [2010], Introduction to Computer Music, Wiley, Chichester.
Cope, David [2004], Virtual Music, The MIT Press, Cambridge.
Dodge, Charles and Thomas A. Jerse [1997], Computer Music, Schirmer.
Farnell, Andy [2010], Designing Sound, The MIT Press, Cambridge.
Giri, Maurizio and Alessandro Cipriani [2009], Musica Elettronica e Sound
Design, ConTempoNet.
Manning, Peter [2004], Electronic and Computer Music, Oxford University
Press, Oxford.
Manzo, V.J. [2011], Max/MSP/Jitter for Music: A Practical Guide to Developing
Interactive Music Systems for Education and More, Oxford University Press,
Oxford.
Puckette, Miller [2007a], The Theory and Technique of Electronic Music, World
Scientific Publishing Company.
Roads, Curtis [1996], The Computer Music Tutorial, The MIT Press, Cam-
bridge.
– [2004], Microsound, The MIT Press, Cambridge.
Rowe, Robert [2004], Machine Musicianship, The MIT Press, Cambridge.
Taube, Heinrich K. [2004], Notes from the Metalevel, Taylor & Francis, Lon-
don.
Temperley, David [2010], Music and Probability, The MIT Press, Cambridge.

240
Winkler, Todd [2001], Composing Interactive Music. Techniques and Ideas Us-
ing Max, The MIT Press, Cambridge.

241
SITOGRAFIA

AA.VV. [2009], Pure Data Floss Manual, un buon manuale di Pure Data in
inglese, http://flossmanuals.net/puredata/.
– [2010a], Pure Data, il sito ufficiale di pd-extended, dove si possono scari-
care tutte le versioni del software e la relativa documentazione, http:
//www.puredata.info/.
Kreidler, Johannes [2011], Programming Electronic Music in Pd, un ottimo
manuale di Pure Data, disponibile in varie lingua, ma non in italiano,
http://www.pd-tutorial.com/.
Puckette, Miller [2007b], The Theory and Technique of Electronic Music, il li-
bro di Miller Puckette, creatore di Max e di Pure Data, scaricabile libera-
mente dal suo sito, http://crca.ucsd.edu/~msp/.
Valle, Andrea [2008], the SuperCollider Italian Manual, un manuale in ital-
iano di SuperCollider, scritto da Andrea Valle e distribuito sotto licenza
Creative Commons, http://www.fonurgia.unito.it/andrea/wikka.php?
wakka=SuperCollider.
Wang, Ge, Cook amd Perry R., et al. [2007], Chuck Manual, il sito dedicato
a Chuck, un altro linguaggio di programmazione dedicato all’audio in
tempo reale. Da qui è possibile scaricare il software dell’ambiente, il
manuale e la documentazione varia, http://chuck.cs.princeton.edu/.

242 242
INDEX

vline∼, 177, 179 Modulazione di Frequenza, 143–


vline∼, 175–178, 189 145

bang, 19 object box, 16

if, 54 print, 15

243 243
INDEX

vline∼, 177, 179 Modulazione di Frequenza, 143–


vline∼, 175–178, 189 145

bang, 19 object box, 16

if, 54 print, 15

244 244

Potrebbero piacerti anche