Inventare il suono con
PURE DATA Manuale introduttivo di musica elettronica vers. 0.1.2
Francesco Bianchi elettrochuck@gmail.com
2010
N OTA SUL C OPYRIGHT Questo documento e il suo contenuto sono rilasciati sotto licenza Creative Commons 2.5 di tipo Attribuzione-Non commercialeCondividi allo stesso modo 2.5 Generico. Sei quindi libero:
• di riprodurre, distribuire, comunicare al pubblico, esporre in pubblico, rappresentare, eseguire e recitare quest’opera • di modificare quest’opera alle seguenti condizioni:
• Attribuzione. Devi attribuire la paternità dell’opera nei modi indicati 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
INDICE
Introduzione
9
i L’AMBIENTE 1 FONDAMENTI 1.1 Cos’è Pure Data? . . . . . . . 1.2 Pd-extended . . . . . . . . . . 1.3 Installazione . . . . . . . . . . 1.3.1 GNU/Linux . . . . . . 1.3.2 Windows e Mac Os X 2 PANORAMICA DELL’AMBIENTE 2.1 Pd window e patch window . . 2.1.1 il motore DSP . . . . . 2.1.2 print . . . . . . . . . . 2.2 Le scatole di Pd . . . . . . . . 2.2.1 oggetti e connessioni . 2.2.2 messaggi e liste . . . . bang e number box . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
10 11 11 12 12 12 13 14 14 15 16 16 16 18 19
. . . . . . . . . . . . . . .
21 22 22 25 26 26 26 27 29 29 30 31 32 32 35 36 37
ii DATI 3 BASI DI PROGRAMMAZIONE CON PURE DATA 3.1 Variabili e costanti . . . . . . . . . . . 3.1.1 pack e unpack . . . . . . . . . . . 3.2 Gestione del tempo . . . . . . . . . . . 3.2.1 metro . . . . . . . . . . . . . . . un contatore . . . . . . . . . . . 3.2.2 line . . . . . . . . . . . . . . . . 3.2.3 delay . . . . . . . . . . . . . . . 3.2.4 line multirampa con delay . . . 3.3 Aritmetica . . . . . . . . . . . . . . . . 3.3.1 operatori aritmetici . . . . . . . 3.3.2 expr . . . . . . . . . . . . . . . . 3.4 Generatori di numeri casuali . . . . . 3.5 Connessioni senza cavi . . . . . . . . . 3.6 Subpatches e Abstractions . . . . . . . . 3.6.1 subpatch . . . . . . . . . . . . .
3
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
Indice
4
5
6 7
3.6.2 abstraction . . . . . . . . . . . . . 3.6.3 graph on parent . . . . . . . . . . VETTORI, GRAFICI E TABELLE 4.1 Vettori . . . . . . . . . . . . . . . . . . . 4.1.1 leggere un vettore . . . . . . . . 4.1.2 l’oggetto table . . . . . . . . . . . PROGRAMMAZIONE AVANZATA 5.1 Istruzioni condizionali . . . . . . . . . . 5.1.1 operatori relazionali . . . . . . . 5.1.2 select . . . . . . . . . . . . . . . . 5.1.3 operatori logici . . . . . . . . . . 5.1.4 If . . . . . . . . . . . . . . . . . . 5.2 loops e iterazioni . . . . . . . . . . . . . . OGGETTI GUI 6.1 Altre GUI dalle librerie di Pd . . . . . . LISTA DEGLI OGGETTI PER MANIPOLARE DATI
. . . . . . . 39 . . . . . . . 41 43 . . . . . . . 43 . . . . . . . 46 . . . . . . . 48 50 . . . . . . . 50 . . . . . . . 50 . . . . . . . 51 . . . . . . . 53 . . . . . . . 56 . . . . . . . 57 60 . . . . . . . 63 66
iii AUDIO 8 L’AUDIO DIGITALE 8.1 L’oscillatore . . . . . . . . . . . . . . . . . . . 8.1.1 frequenza e ampiezza del segnale . . 8.1.2 osc∼ . . . . . . . . . . . . . . . . . . . 8.1.3 tabwrite∼ . . . . . . . . . . . . . . . . 8.1.4 la rappresentazione del suono . . . . 8.2 Le forme d’onda . . . . . . . . . . . . . . . . . 8.2.1 tabosc4∼ . . . . . . . . . . . . . . . . 8.2.2 onda quadra . . . . . . . . . . . . . . . pulse width modulation (PWM) . . . 8.2.3 onda a dente di sega . . . . . . . . . . phasor∼ . . . . . . . . . . . . . . . . . 8.2.4 onda triangolare . . . . . . . . . . . . 9 IL panning 9.1 l’oggetto dac∼ . . . . . . . . . . . . . . . . . . 9.2 Controllo del panning . . . . . . . . . . . . . . 9.2.1 Segnali bipolari e unipolari . . . . . . 9.2.2 il DC offset . . . . . . . . . . . . . . . 10 SINTESI ADDITIVA, SINTESI TABELLARE E SINTESI TORIALE 10.1 Operatori di segnale . . . . . . . . . . . . . . 10.1.1 expr∼ . . . . . . . . . . . . . . . . . .
4
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . . VET-
. . . .
67 68 68 70 73 74 74 78 79 79 82 85 86 86 90 90 91 93 93
97 . . . . 97 . . . . 97
Indice
11
12
13
14
10.2 Sintesi additiva . . . . . . . . . . . . . . . . . . . . . 97 10.2.1 sintesi additiva a spettro armonico . . . . . . 97 10.2.2 sintesi additiva a spettro non armonico . . . 97 10.2.3 spettro fisso . . . . . . . . . . . . . . . . . . . 97 10.2.4 spettro variabile . . . . . . . . . . . . . . . . . 97 10.3 Sintesi vettoriale . . . . . . . . . . . . . . . . . . . . . 97 10.3.1 dissolvenza incrociata automatica fra due tabelle . . . . . . . . . . . . . . . . . . . . . . 97 10.3.2 dissolvenza incrociata automatica fra più tabelle . . . . . . . . . . . . . . . . . . . . . . 97 10.3.3 algoritmo di selezione per il crossfading fra tabelle . . . . . . . . . . . . . . . . . . . . . . 97 10.3.4 controllo del crossfading attraverso grid . . . 97 SINTESI SOTTRATTIVA 98 11.1 La sintesi sottrattiva . . . . . . . . . . . . . . . . . . 98 11.1.1 il rumore . . . . . . . . . . . . . . . . . . . . . 98 11.2 I filtri . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 11.2.1 filtri passa-alto . . . . . . . . . . . . . . . . . 101 11.2.2 filtri passa-basso . . . . . . . . . . . . . . . . 101 11.2.3 filtri passa-banda . . . . . . . . . . . . . . . . 101 11.2.4 filtri escludi-banda . . . . . . . . . . . . . . . 101 11.2.5 gli ordini dei filtri . . . . . . . . . . . . . . . . 101 MOULAZIONE AD ANELLO (RM), TREMOLO, MODULAZIONE D’AMPIEZZA (AM) 102 12.1 La modulazione ad anello . . . . . . . . . . . . . . . 102 12.2 Segnali bipolari e unipolari . . . . . . . . . . . . . . 105 12.3 Segnale di controllo dell’ampiezza: il tremolo . . . 106 12.4 La modulazione d’ampiezza . . . . . . . . . . . . . . 109 12.4.1 l’indice di modulazione . . . . . . . . . . . . 112 VIBRATO E MODULAZIONE DI FREQUENZA (FM) 116 13.1 Segnale di controllo della frequenza: il vibrato . . . 116 13.2 Modulazione di frequenza . . . . . . . . . . . . . . . 117 13.2.1 l’inviluppo . . . . . . . . . . . . . . . . . . . . 119 13.2.2 FM a spettro variabile . . . . . . . . . . . . . 123 13.2.3 algoritmo per il controllo random dei parametri124 13.3 Portanti multiple . . . . . . . . . . . . . . . . . . . . 124 13.4 Modulanti multiple . . . . . . . . . . . . . . . . . . . 124 SINTESI PER DISTORSIONE NON LINEARE (DNL) 128 14.1 Ancora sulle tabelle . . . . . . . . . . . . . . . . . . . 128 14.2 Teoria della sintesi per distorsione non lineare . . . 128
5
Indice 14.3 Sintesi per distorsione non lineare . . . . . . . 15 INTRODUZIONE ALLA SINTESI GRANULARE 15.1 Teoria della sintesi granulare . . . . . . . . . . 15.1.1 Panoramica dei tipi di sintesi granulare 15.2 Algoritmo per la sintesi Pulsar . . . . . . . . . 16 ALTRE APPLICAZIONI DI PURE DATA 16.1 GEM e il video . . . . . . . . . . . . . . . . . . 16.1.1 un esempio con GEM . . . . . . . . . . 16.2 Arduino . . . . . . . . . . . . . . . . . . . . . . 16.2.1 pduino . . . . . . . . . . . . . . . . . . . 16.3 Il protocollo osc . . . . . . . . . . . . . . . . . . 16.3.1 netsend e netreceive . . . . . . . . . . . . 16.4 Il Live coding . . . . . . . . . . . . . . . . . . . . 16.4.1 suonare in rete: oggcastâˆź . . . . . . . . Conclusione Bibliografia Sitografia Indice analitico
6
. . . 128 129 . . . 129 . . . 129 . . . 129 130 . . . 130 . . . 130 . . . 130 . . . 130 . . . 130 . . . 130 . . . 130 . . . 130 131 131 131 131
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 manipolazione dell’audio e oggi chiunque può trovare in rete o in commercio programmi per produrre il proprio brano o il proprio disco di musica elettronica, spesso senza il bisogno di conoscere a fondo i principi, il funzionamento 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, leggittimamente, perché dovrebbe leggere un manuale di musica elettronica. Il panorama del software è talmente vasto che chiunque può trovare il programma adatto alle sue esigenze, in linea con le proprie conoscenze informatiche 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 compito 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
7
Indice queste tecniche bisogna acquistarlo o bisogna accontentarsi di prodotti che non danno ottimi risultati. - Questi programmi possono costare molto, soprattutto i migliori. Se si volessero avere dei sintetizzatori per realizzare 3 o 4 tecniche di sintesi del suono si dovrebbero acquistare 3 o 4 prodotti commerciali diversi, questo a scapito del portafogli e del fatto che probabilmente fra qualche anno saranno obsoleti e diverranno quindi praticamente inutili. 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 commerciali 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 studiare 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 complessi. 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 pro-
8
Indice grammi liberi sono tali in tutto e per tutto nella maggior parte dei casi. Si può prelevare il sorgente, studiarlo, modificarlo e redistribuirlo. Non a caso intorno a questi software ci sono delle vere e proprie comunità che si scambiano opinioni, idee e progetti, condividendo liberamente il proprio pensiero con altri. – 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 software libero. Buon divertimento!
9
Parte 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 . Cerchiamo di entrare nel dettaglio di questa descrizione. Pure Data è prima di tutto un linguaggio di programmazione perché consente di realizzare algoritmi 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 sintetizzatori 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 algoritmi 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 cambiare 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, 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
1.2 PD-EXTENDED musicisti, hackers e appassionati 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, studiati, modificati e redistribuiti da chiunque. Inoltre Pure Data è multipiattaforma, 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 commerciale3 . 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 standard, 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 sul sistema Ubuntu GNU/ Linux, sistema operativo sul quale è stato scritto il presente manuale e al quale ci riferiamo citando le combinazione 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 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
1.3 INSTALLAZIONE nel caso si stia operando in una distribuzione Ubuntu Hardy, in caso diverso sostituire la dicitura hardy con il mome della distribuzione di Ubuntu installata. 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 semplicemente: 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 window) che ha due funzioni principali: - mostrare dei messaggi - consentire la configurazione dell’audio e del MIDI e definire i percorsi 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 configurazione 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 .
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
2.1 PD window E patch window Nella versione extended il Path e lo Startup sono già impostati per caricare la maggior parte delle librerie necessarie per una completa funzionalità 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 simile 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 rapidissimi 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 successivamente le altre possibilità di intervenire sull’attivazione e la disattivazione del motore DSP, quando si tratterà dell’audio nella seconda parte del presente manuale.
15
2.2 LE scatole DI PD 2.1.2 print
Durante l’esecuzione delle patch può accadere che vengano automaticamente visualizzati dei messaggi nella Pd window, in particolare alla presenza di errori, ma c’è un oggetto che permette al programmatore di visualizzare nella Pd window il messaggio o dato che desidera. Si tratta di print, 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 Figura 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, messaggi, 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 oggetti, rappresentati dalle object box, caratterizzate dalla forma rettangolare 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.
16
le object box
2.2 LE scatole DI PD 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 . random 250
Figura 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 è raggiunto l’inlet di arrivo. random
+
select 0 5 7
Figura 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 temporaneamente all’interno dell’oggetto, fino a che lo stesso non viene processato all’attivazione dell’inlet caldo. Come già detto, gli oggetti insistono su dati o segnali audio. Graficamente gli oggetti-audio si distinguono da quelli per i dati 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 espressione. Per approfondire: www.diee.unica. it/~roli/IA/Materiale%20didattico/AA0910/Lisp.pdf
17
2.2 LE scatole DI PD counter
pack 0 0 Figura 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
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~
Figura 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. Possono contenere stringhe di caratteri, numeri, liste o variabili e vengono attivati con un click del mouse quando si è in run mode oppure alla ricezione di un altro messaggio o di particolari azioni.
18
2.2 LE scatole DI PD
questo è un messaggio print
Figura 6: un click con il mouse sul messaggio produce un output del messaggio stesso nella Pd window
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
Figura 7: la stessa patch precedente, con la differenza che il messaggio viene attivato 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. 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 numero stesso. Per comodità è possibile stabilire eventuali minimi e massimi della number box premendo il destro del mouse e andando sulle proprietà del-
19
2.2 LE scatole DI PD
bang grafico bang b
oggetti bang
Figura 8: le varie versioni del bang
l’oggetto3 . Una number box può inviare o ricevere dati attraverso i suoi inlet. 7
+ 5
12
Figura 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
Parte II DAT I
3 B A S I D I P R O G R A M M A Z I O N E C O N 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 esempio 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. 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 cambiare 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 addendi e di far uscire il risultato.
22
3.1 VARIABILI E COSTANTI
10
20
+ 5
30 Figura 10: è possibile cambiare a piacimento gli addendi della somma
Nel caso di questo oggetto è sufficiente inserire nell’inlet di sinistra un bang, collegato all’uscita del secondo addendo, che ordina all’object box di far uscire il risultato immediatamente1 . 14
3
+ 5
17 Figura 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 è 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
23
3.1 VARIABILI E COSTANTI possibile si può ricorrere al’oggetto loadbang che attiva un bang all’apertura della patch (figura 12). loadbang 7
+ 5 12 Figura 12: all’apertura della patch si avrà come output la somma fra 7 e 12
Vi sono circostanze in cui è necessario specificare delle variabili all’interno delle object box. Questo è possibile attraverso il simbolo $n, dove n è un 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 Figura 13: variabile in una message box, osservare l’output nella Pd window
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. . .
24
3.1 VARIABILI E COSTANTI 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, 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 Figura 14: pack: un click sul bang senza cambiare i valori delle number box produce l’uscita dei valori inizializzati. Una variazione delle number box produce 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 convoglia i singoli atomi attraverso i suoi inlet.
25
3.2 GESTIONE DEL TEMPO
20 1 2010 unpack 0 0 0
20
1
2010
Figura 15: unpack: un click sulla message box produce un output in ognuno dei tre outlet
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. Esamineremo alcuni di questi senza dimenticare che la presente trattazione non può trattare di molti altri oggetti che il programmatore scoprirà nel suo cammino3 . 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. 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) 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. 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
3.2 GESTIONE DEL TEMPO
1
un numero diverso da 0 o un "bang" attivano metro bang 0 0 o "stop" fermano metro stop 0
metro 500
l'inlet di sinistra consente di modificare la distanza temporale fra i "bang" Figura 16: metro
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 destro 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 raggiungere un determinato valore. line ha bisogno di almeno due argomenti, il valore-obiettivo, cioè la quantità da raggiungere, e il tempo in millisecondi 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).
27
3.2 GESTIONE DEL TEMPO
0
1
metro 500
loadbang 0 int + 1
23 Figura 17: click su 1 per avviare il contatore, su 0 per fermarlo
Un oggetto molto comune in Pd è line, che generara delle rampe per raggiungere 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 esempio 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 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)
28
3.2 GESTIONE DEL TEMPO
1000 5000 line 0 Figura 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 0 Figura 19: si può ricominciare la rampa da 0 a 1000 ogni volta che si preme sulla message box
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). 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
29
3.3 ARITMETICA
2000 5000 line 1000 500 0 Figura 20: rampa da 1000 a 2000 in 5 secondi, con step di mezzo secondo fra un valore e l’altro in uscita
1 0 metro 1000 delay 500
Figura 21: i bang saranno intermittenti
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ù comuni operazioni matematiche. Abbiamo già incontrato l’oggetto ’+’ che permette l’operazione di somma. Nel prossimo paragrafo esamineremo alcuni altri oggetti per operare sui numeri.
30
3.3 ARITMETICA
0, 127 1000
delay 1000
delay 1600
50 600
100 1500
line 0
Figura 22: click sul bang più in alto della patch
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. Successivamente avremo modo di usarli massicciamente. Operazioni aritmetiche:
• + • • * • / • pow Operazioni trigonometriche:
• sin • cos • tan
31
3.4 GENERATORI DI NUMERI CASUALI
• atan • atan2 Operazioni sulle frazioni
• mod • div e molti altri... 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 possono 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 rappresentare 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. 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 compreso 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 vengono generati da algoritmi. Nel caso di Pd alla base
32
3.4 GENERATORI DI NUMERI CASUALI
4
+ 12
* 24
expr (($f1 + 12) * 24)/(($f1 + 12) - 7)
- 7
/ 42.6667
42.6667
Figura 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
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. 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 vengono convogliati dall’outlet sinistro, quelli al di sopra da quello destro.
33
3.4 GENERATORI DI NUMERI CASUALI
1
0
metro 500 random 250 0 Figura 24: la patch genera un numero pseudo-casuale ogni mezzo secondo
1
0
metro 500 random 1001 / 1000 0 Figura 25: la patch genera un numero pseudo-casuale compreso fra 0 e 1, con 3 cifre decimali
L’oggetto decide produce pseudo-casualmente solo sequenze di 0 e 1, mentre 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, frutto di drunk è molto più ordinata: gli elementi della sequenza si spostano entro un range limitato (definito dal secondo argomento di drunk).
34
3.5 CONNESSIONI SENZA CAVI
1
0
metro 500 random 100 moses 25
Figura 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%
1
0
metro 500 drunk 100 10 80 Figura 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
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 riceveranno
35
3.6 subpatches E abstractions
random
drunk
Figura 28: in alto la sequenza generata da random, in basso quella creata con drunk, con una stepsize di 25
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
36
3.6 subpatches E abstractions
4
r numero
send numero 4
receive numero
r numero * 2
4 8 Figura 29: connessioni senza fili
pd seguito da un nome identificativo per la subpatch, esse possono essere utilizzate solo allinterno della patch dove sono state create o all’interno di altre subpatch della stessa patch. Le abstraction invece, pur apparendo come delle normali object box, hanno solo un nome identificativo, 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 qualsisasi 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 attraverso il quale vengono emessi dei bang da quattro outlet diversi, il primo 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 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.
37
3.6 subpatches E abstractions
metro 500 random 500 + 1 moses 250 moses 126
moses 376
Figura 30: un semplice algoritmo senza annidamenti
pd miasubpatch
Figura 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 qualunque momento e, soprattutto, possono essere duplicate a piacimento. Rappresentano uno strumento molto comodo per rendere più leggibile e chiaro un algoritmo nella patch window, quindi il consiglio è di usarle il più possibile.
38
3.6 subpatches E abstractions
inlet metro 500 random 500 + 1 moses 250 moses 126
moses 376
outlet
outlet
outlet
outlet
Figura 32: l’interno della subpatch con gli inlet e gli outlet
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 subpatch, 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 argomen-
39
3.6 subpatches E abstractions ti) 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 0 Figura 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
inlet pack $1 $2 line outlet Figura 34: l’interno dell’abstraction
l’object box myabstraction si sostituiscono 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.
40
3.6 subpatches E abstractions 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 sistema funziona su entrambe), cui si accede premendo il sinistro del mouse su un punto qualunque della subpatch window, selezioniamo l’opzione graph on parent, comprarirà all’interno della subpatch stessa un riquadro all’interno del quale possiamo mettere ciò che vogliamo sia visibile dalla patch genitrice. Gli oggetti consentiti sono essenzialmente GUI’s, quindi number box, sliders, radio button etc. . .
1
0
pd submetro
regola_metro 301
Figura 35: Una subpatch con una number box in graph on parent
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.
41
3.6 subpatches E abstractions
inlet
regola_metro 301
metro 500
outlet Figura 36: l’interno della subpatch. Per creare il riquadro di visibilità basta andare sulle proprietà della subpatch e selezionare l’opzione graph on parent
42
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 manipolare comodamente una grande quantità di dati. Può essere pensato come un contenitore di locazioni di memoria, identificate da un indice, attraverso 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 rappresentano le coordinate (x, y) degli elementi
43
4.1 VETTORI
i 10
5
0 0
1
2
3
Figura 37: vettori: sull’asse delle ascisse c’è l’indice, sull’ordinata il valore
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 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 message box l’indice del primo elemento da scrivere seguito da tutti i valori da inserire nel vettore. Si possono
44
4.1 VETTORI 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 cosinusoidi. 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). - 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 entrano 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). 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 pseudocasuali decimali, compresi fra 0 e 2, dall’oggetto randomF. Da questi ultimi viene sottratto 1 in modo da avere 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 elementi come un etichetta che rappresenta l’ordinata e uno che rappresenta l’ascissa. Questi elementi si possono aggiungere tramite message box secondo le seguenti sintassi: 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.
45
4.1 VETTORI
i
; 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 Figura 38: attivare le tre message box con un click e verificarne il risultato sul grafico. Il comando resize ridimensiona il vettore secondo quanto indicato dal suo argomento, in questo caso 32
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 interpolati (polygon) cioè singoli punti uniti da una linea che traccia il percorso più breve fra punti adiacenti, infine come curva di bézier (bezier) che addolcisce gli spigoli (figura 41). 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
46
4.1 VETTORI
i 1
0
-1 32
until 1 int 1 + 1 randomF 2 - 1 tabwrite i Figura 39: click sulla message box in alto e verificare il risultato sul grafico
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.
47
4.1 VETTORI
i 1
0
-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
Figura 40: click sulle message box per aggiungere o rimuovere le etichette
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.
48
4.1 VETTORI i
punti
i
bezier
i
polygon
Figura 41: le tre diverse rappresentazioni di un vettore di 16 punti
i
reset 16 s reset until
0 0 int 1
0
+ 1
tabwrite new new
metro 1000 r reset 0 int 0
+ 1
mod 16 t i i
sel 15
tabread i
$1 950
0, $1 950
line
line
size $1
tabwrite new
Figura 42: click sulle message box per aggiungere o rimuovere le etichette
49
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 strumenti 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.
50
5.1 ISTRUZIONI CONDIZIONALI
0
> 10
0 Figura 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
0 Figura 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 soddisfano 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).
51
5.1 ISTRUZIONI CONDIZIONALI
5 4 123 10 sel 10 4
0 Figura 45: select con più selezioni
20
32
69
> 50 sel 1 0, 127 2000 line
Figura 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 strumento 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 solo alla prima
52
5.1 ISTRUZIONI CONDIZIONALI entrata. Combinando così ’>’ e change possiamo soddisfare la nostra richiesta.
0, 100 2000 line 100 > 50 change sel 1
0, 127 2000 line
Figura 47: click sulla message box in alto
Esaminiamo la patch in figura 47: all’attivazione della rampa, inizia il cammino 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 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.
53
5.1 ISTRUZIONI CONDIZIONALI al livello di bit e altri che operano sui numeri decimali. Nel primo caso i numeri interi decimali ricevuti dagli operatori logici vengono trasformati nella loro forma binaria e ogni bit viene valutato con il bit dell’altro numero che si trova nella stessa posizione. 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 1 1
0 1 0 1
0 0 0 1
Tabella 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 6
= =
1 0
0 0
1 1
0 1
1 0
4
=
0
0
1
0
0
∧ =
Tabella 2: operazione AND su gli interi 21 e 6
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 1 1
0 1 0 1
0 1 1 1
Tabella 3: tavola di verità per 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
54
5.1 ISTRUZIONI CONDIZIONALI
t b b
21
6
& 4 Figura 48: l’operatore AND in azione in una patch di Pd
t b b 41
22
| 63 Figura 49: l’operatore OR
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 esempio, converte l’intero che riceve nel suo inlet sinistro nella sua forma binaria 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.
55
5.1 ISTRUZIONI CONDIZIONALI
10
10
&& 1 Figura 50: l’operatore ’&& ’ confronta due valori in base alla tavolà di verità per AND
113
=
452
=
1
1
1
1
1
0
0
0
1 2
1
0
0
0
1
0
0
<< =
Tabella 4: scivola a sinistra di due posizioni
t b b 113 2
<< 452 Figura 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 affrontare il costrutto if. Pd non dispone di un oggetto if, ma consente di usare questo comando all’interno dell’oggetto expr che abbiamo già incontrato (sezione 3.3.2). Nei comuni linguag-
56
5.2 loops E ITERAZIONI gi di programmazione l’istruzione 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: i f ( espressione ) f a i una c e r t a cosa ; else fanne un ’ a l t r a ; 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)
0 expr if ($f1 < 10, $f1 * 5, 10) 0 Figura 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 ripetizione, finché non viene spento. E’ semplice quindi inserire un contatore che si occupa di contare i bang usciti e appena raggiungo il valore desiderato 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
57
5.2 loops E ITERAZIONI 1
0
metro 500
loadbang 0 float + 1 sel 9
0
Figura 53: la patch produce 10 bang attraverso un oggetto metro controllato da un contatore e da un selettore
differenza della patch in figura 53 until non è orientato al tempo ma opera quasi istantaneamente come nei tradizionali linguaggi di programmazione. In effetti until funziona secondo lo schema classico di un ciclo for del C: f o r ( i = 0 ; i < 1 0 0 ; 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: f o r ( i = 0 ; i < 1 0 0 ; i ++) p r i n t f ("%d " , i ) ; Nella figura 54 si vede la patch di Pd che fa la stessa cosa.
58
5.2 loops E ITERAZIONI
100 until loadbang 0 int + 1 print Figura 54: ciclo until: valutare lâ&#x20AC;&#x2122;algoritmo con un click sulla message box in alto e osservare il risultato nella Pd window
59
6 OGGETTI GUI
Nel corso dei nostri primi esperimenti abbiamo già avuto modo di incontrare alcuni oggetti grafici, che nell’ambito del mondo informatico sono dette GUI (graphical user interfaces). Pd mette a disposizione un certo numero 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, accessibili 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 55).
60
OGGETTI GUI 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 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
Figura 55: l’oggetto toggle
Nella figura 55 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. 56) 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 sommato 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’è
61
OGGETTI GUI
r slide metro 100 int 1
expr ($f1 / 127) * 20
+ 1
mod 2
* 10
r slide manovrare_da_qui
expr (127 - $i1)
$1 90 line
+
Figura 56: lo slider verticale a sinistra pilota gli altri due
nessun send! Le GUI infatti possono mandare o ricevere messaggi senza bisogno di creare oggetti e supplementari. Possiedono degli oggetti send e receive incorporati che possono essere impostati dalle properties della GUI stessa. I radio button sono oggetti formati da barrette orizzontali o verticali costituite 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
62
6.1 ALTRE GUI DALLE LIBRERIE DI PD 16 elementi, avrà un output che va da 0 a 15. In figura 57 due radio button disegnano un grafico. Unica annotazione, i valori del radio button verticale vengono invertiti per consentire un migliore adesione al grafico, così il primo valore in alto diventa 9 in luogo di zero, il secondo 8 invece che 1, etc. . . . Della GUI VU-meter avremo modo di scrivere nella parte che riguarda l’audio, mentre possiamo ora accennare alle canvas che sono oggetti semplici 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. 6.1 A LTRE GUI DALLE LIBRERIE DI P D Oltre alle GUI native che abbiamo appena discusso, diamo ora una panoramica 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 emettono la posizione del mouse (x, y) dai due outlet alla pressione di quest’ultimo. knob è la classica manopola tipo sintetizzatore analogico. Ha un’unica uscita 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 approfonditamente 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
63
6.1 ALTRE GUI DALLE LIBRERIE DI PD
array1
r ordinata expr (9 - $i1) r ascissa tabwrite array1 Figura 57: impostare prima l’indice (radio button) orizzontale, poi il valore con quello verticale
o ’b’. Non è importante la bellezza estetica di una patch quanto la sua chiarezza, quindi è meglio evitare troppi oggetti grafici e
64
6.1 ALTRE GUI DALLE LIBRERIE DI PD abbondare, al contrario, di subpatches e annidamenti.
65
7 L I S TA D E G L I O G G E T T I P E R M A N I P O L A R E DAT I
66
Parte III 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 generato 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. 58), 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 permette 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 sinusoidale, 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 indicato 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 1 http://it.wikipedia.org/wiki/Sinusoide
68
8.1 L’OSCILLATORE
1 −2
−1
0
0 −2
−1
ampiezza
1
2
2
Parametri di una sinusoide
tempo Figura 58: il grafico di una funzione sinusoidale
approssimerà la forma d’onda desiderata, pur non riuscendo a costruirne una identica a quella analogica (fig. 59). In Pd l’oscillatore digitale è implementato nell’oggetto osc∼. Nella patch in figura 60 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 funzione sinusoidale in tempo reale, ma usano un sistema che rende le cose più veloci. Piuttosto che fare 44100 calcoli di funzioni sinusoidali al secondo è preferibile leggere delle tabelle che hanno i valori di una funzione 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 61 è mostrata la rappresentazione grafica di una wavetable: sull’asse delle ascisse c’è l’indice, su quella delle ordinate il valore di ampiezza. Nella memoria del vettore 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), . . .
69
8.1 L’OSCILLATORE
0.5 −1.0
−0.5
0.0
0.0 −1.0
−0.5
ampiezza
0.5
1.0
1.0
Sinusoide digitale
tempo Figura 59: il grafico di una funzione sinusoidale prodotta da un calcolatore
L’oggetto osc∼ legge una cosinusoide scritta in una wavetable di 512 punti. La cosinusoide graficamente è identica ad una sinusoide, con l’unica differenza che la sinusoide ha come primo valore 0, mentre la cosinusoide 1, quindi è sfasata rispetto alla prima di π2 (vedi fig. 62). L’oggetto tabosc4∼ implementa un lettore di wavetable generiche, dove è possibile disegnare una forma d’onda qualunque e sceglierne la dimensione. 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 identica ad intervalli di tempo regolari. Il periodo è quindi il tempo necessario 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 frequenza,
70
8.1 L’OSCILLATORE
osc~ 440
dac~
2
3
Wavetable 5 6
4
●
●
10
●
●
●
●
0
−0.5
−0.5
0.0
9
●
●
0.5
8
●
●
ampiezza
7
●
1.0
1
0.5
0
0.0
1.0
Figura 60: l’oscillatore di Pd
1
2
3
4
5
6
7
8
9
10
index Figura 61: una cosinusoide
ovvero il numero di cicli completi dell’onda per secondo. Questo valore si misura in hertz (vedi fig. 63). 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 invece 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,
71
8.1 L’OSCILLATORE
0.5 −1.0
−0.5
0.0
0.0 −1.0
−0.5
ampiezza
0.5
1.0
1.0
Cosinusoide
tempo Figura 62: una cosinusoide
2
2
Parametri di una sinusoide
➤
❘
λ
➤ ❘
1
❘
❘
A 0 −2
−2
−1
−1
0
❘
➤
ampiezza
❘
➤
➤
1
➤
τ
tempo Figura 63: parametri di una forma d’onda. A = ampiezza, τ = periodo, λ = lunghezza d’onda
superato tale limite il segnale distorce. La frequenza è responsabile della percezione dell’altezza, mentre l’ampiezza dell’intensità del segnale.
72
8.1 L’OSCILLATORE 8.1.2 osc∼
L’object box osc∼ implementa un oscillatore digitale. Accetta come argomento interno la frequenza (fig. 60) il cui valore può anche essere variato dall’inlet di sinistra (fig. 64). Come vedremo successivamente oltre che dati, l’inlet di sinistra accetta anche segnali per controllare la frequenza.
242 osc~ 200
dac~ Figura 64: l’oggetto osc∼ con frequenza controllata da una number box
Nella patch in figura 65 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~ Figura 65: la realizzazione di un glissando con l’oggetto line
Volendo invece intervenire sull’ampiezza del segnale, è necessario utilizzare un moltiplicatore, come un oggetto *∼, per moltiplicare l’ampiezza istantanea del segnale per un fattore costante
73
8.1 L’OSCILLATORE (o variabile). In figura 66 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 67 è mostrata un’onda con ampiezza di picco 1, e una con ampiezza di picco 0.5.
osc~ 440
*~ 0.5
dac~ Figura 66: 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 68 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 per evitare che l’ampiezza cambi troppo repentinamente producendo un effetto scalino. 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 69 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 segnale. 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 disegnato un punto in corrispondenza del-
74
−0.5
0.0
−0.5
0.0 −1.0
−1.0
−0.5
b)
0.0
0.5
0.5
1.0 −1.0
1.0 −1.0
−0.5
a)
0.0
0.5
0.5
1.0
1.0
8.1 L’OSCILLATORE
Figura 67: la realizzazione di un glissando con l’oggetto line
amp
osc~ 440
*~ 0.5
dac~ $1 20 line
Figura 68: la realizzazione di un glissando con l’oggetto line
l’ampiezza del segnale. Il risultato di tale operazione permette di visualizzare la forma d’onda. In figura 70 è rappresentato un ciclo di un’onda periodica complessa, formata dalla somma di 3 sinusoidi. Come già detto ques-
75
8.1 L’OSCILLATORE 883
amp
r~ sig osc~ 440 amp
*~ 0.5
metro 100
tabwrite~ amp
dac~ $1 20 send~ sig line
Figura 69: la realizzazione di un glissando con l’oggetto line
ta 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 rappresentare ogni singola frequenza. Attraverso algoritmi che operano tali scomposizioni è possibile analizzare lo spettro di un suono, cioè la sua 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. 71) 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 digitalmente (probabilmente nemmeno un suono elettrico analogico resta sempre 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.
76
8.1 L’OSCILLATORE
0.5 −0.5
0.0
0.0 −0.5
ampiezza
0.5
Rappresentazione della forma d’onda
tempo Figura 70: forma d’ondarisultante dalla somma di 3 sinusoidi
ampiezza
Spettrogramma ampiezza/frequenza
0
100
200
300
400
500
600
700
800
900
1000
frequenza Figura 71: analizzatore di spettro bidimensionale, sull’asse delle ascisse c’è la frequenza, su quella delle ordinate l’ampiezza. Il suono è costituito dalla somma di onde di frequenza pari a 400, 700 e 800 hz
77
8.2 LE FORME D’ONDA
800 600
600
400
400
0
0
200
200
frequenza
1000
Spettrogramma ampiezza/frequenza/tempo
800
1000
Gli analizzatori del secondo tipo permettono di dare una visione più dettagliata e pertinente del suono perché rappresentano l’ampiezza e la frequenza 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 72 c’è il tempo sull’asse delle ascisse e la frequenza su quella delle ordinate, mentre l’ampiezza è rappresentata dal colore delle linee: nero per la massima ampiezza e varie tonalità di grigio per ampiezza minore, fino al bianco, quando c’è assenza di suono.
tempo Figura 72: l’ampiezza delle sinusoidi è rappresentata dal-ìintensità del colore delle linee
8.2 L E FORME D ’ ONDA Oltre alla forma d’onda più semplice, quella sinusoidale, che abbiamo esaminato nella sezione precedente, esistono altre forme d’onda periodiche. Il numero di esse è teoricamente infinito, anche se esistono alcune forme d’onda classiche che si possono ottenere dalla somma di sinusoidi semplici in rapporto 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.
78
8.2 LE FORME D’ONDA 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 trasformare 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 - 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 73: 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. 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, generalmente 1 e -1, ma anche 1 e 0 se si usa come segnale di controllo. 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 disegnare in un vettore una forma d’onda ottenuta dalla somma di sinusoidi tramite il comando sinesum. L’onda quadra si ottiene dalla somma degli armonici dispari con ampiezza inversamente proporzionale al numero d’ordine dell’armonico, schematizzando: 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
79
8.2 LE FORME D’ONDA frq
sine
0
tabosc4~ sine amp
$1 20
wave
line *~ start
metro 100 dac~
tabwrite~ wave
Figura 73: l’uso di tabosc∼ per leggere un vettore con una forma d’onda sinusoidale
arm 1 1
arm 2 0
arm 3 1 3
arm 4 0
arm 5 1 5
arm 6 0
arm 7 1 7
è possibile costruire un algoritmo per disegnare la forma d’onda nel vettore. In figura 75 ci sono 3 forme d’onda diverse, due realizzate con il comando sinesum, una con un algoritmo. 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 armonici, 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 armonici di quello di quadra40, che a sua volta è meno ricco di quello di quadralg.
80
8.2 LE FORME D’ONDA
1 −2
−1
0
0 −2
−1
ampiezza
1
2
2
Onda quadra
tempo Figura 74: un’onda quadra che alterna i valori 1 e -1 quadra9
0
quadra40
set quadra40 set quadra9 set quadralg tabosc4~ quadra9
dac~
; quadra9 sinesum 512 1 0 0.33 0 0.2 0 0.1428 0 0.1111; quadra9 normalize 1 ; 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
Figura 75: tre tipi diversi di onda quadra
81
8.2 LE FORME D’ONDA 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 intervenire direttamente su un segnale sinusoidale e modificarlo in tempo reale. Nella patch di figura 76 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. wave
150 osc~ 200 expr~ if (($v1 > 0), 1, -1)
metro 100 dac~ tabwrite~ wave
Figura 76: onda quadra generata mediante intervento diretto su un segnale sinusoidale
L’oggetto expr∼ è l’omologo di expr per i segnali. Oltre a operare sulle solite variabili numeriche ($fn o $in) può processare direttamente segnale. 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 sinusoidale. 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 rupercussioni 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
82
8.2 LE FORME D’ONDA di 3:1 rispetto a quella negativa. In figura 77 l’oggetto expr∼ è modificato rispetto a quello della figura 76. 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 avessimo 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. duty cycle (0 - 100)
frq 200
wave
75
osc~ 200
$1 40 line expr ((1 - ($f1 / 100)) * 2) - 1 expr~ if (($v1 > $f2), 1, -1)
metro 100 dac~ tabwrite~ wave
Figura 77: duty cycle dell’onda quadra
Questa modificazione del duty cycle può essere gestita da un segnale, generalmente 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 cosid-
83
8.2 LE FORME D’ONDA detta Pulse Width Modulation, utilizzata in molti sintetizzatori analogici negli anni ’70. In figura 78 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.
wave
frq 300 osc~ 200
osc~ 0.25 *~ 0.99 expr~ if (($v1 > $v2), 1, -1)
metro 100 dac~ tabwrite~ wave Figura 78: variazione del duty cycle tramite un segnale di controllo
84
8.2 LE FORME D’ONDA 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: arm 1 -1
arm 2 − 21
arm 3 − 13
arm 4 − 14
arm 5 − 15
arm 6 − 16
arm 7 − 17
In figura 79 ci sono due forme d’onda a dente di sega ottenute l’una con il comando sinesum l’altra con un algoritmo. 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
Figura 79: l’onda a dente di sega ottenuta in due modi diversi
85
8.2 LE FORME D’ONDA 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 positivo, ovvero con valori che si muovono linearmente da 0 a 1. Tale oggetto è phasor∼, utile per moltissime applicazioni. phasor~ 100
saw
metro 120 tabwrite~ saw Figura 80: l’onda a dente di sega come segnale di controllo, generata con phasor∼
Uno degli usi di phasor∼ è quello di utilizzarlo come segnale da modificare con l’oggetto expr∼ in modo molto versatile. Ad esempio è possibile costruire una patch per la Pulse Width Modulation con un algoritmo più semplice di quello presentato in 8.2.2. La patch si può osservare in figura 81. 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: - vettore e comando sinesum - vettore disegnato da algoritmo - intervento diretto sul segnale
86
8.2 LE FORME D’ONDA osc~ 0.125 phasor~ 400 expr~ ($v1 * 0.49) + 0.5 expr~ if (($v1 > $v2), 1, -1)
dac~
Figura 81: l’onda a dente di sega come segnale di controllo, generata con phasor∼
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 1
arm 2 0
arm 3 − 312
arm 4 0
arm 5 1 52
arm 6 0
arm 7 − 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 secondo da 1 a -1, il terzo da -1 a 0. In figura 82 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 (83) è mostrato l’algoritmo per disegnarla. 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. 85).
87
8.2 LE FORME D’ONDA 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
Figura 82: nel grafico triang l’onda triangolare è approssimata con la somma di 19 armonici, mentre in triang2 l’onda è disegnata in modo perfetto
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
Figura 83: l’algoritmo per produrre una forma d’onda triangolare, in una tabella di 512 + 3 punti
88
8.2 LE FORME Dâ&#x20AC;&#x2122;ONDA
phasor~ 200 expr~ if (($v1 < 0.5), (($v1 * 2) * 2) - 1, (1 - (($v1 * 2)-1)) * 2 - 1) tri
metro 100 dac~
tabwrite~ tri
Figura 84
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
Figura 85
89
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 smistandolo 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~
Figura 86: 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 86(1) il segnale viene inviato solo al canale sinistro, mentre in (2) il segnale avrà un peso maggiore sul canale sinistro
90
9.2 CONTROLLO DEL panning poiché prima di essere collegato al canale destro viene ridotto in ampiezza. 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~ Figura 87
In figura 87 è 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 po-
91
9.2 CONTROLLO DEL panning sizionare 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 compreso 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’ necessario inoltre calcolare la radice quadrata dei due valori, poiché l’intensità del suono percepito è proporzionale al quadrato dell’ampiezza del segnale stesso. Entrambi i dati in uscita vengono infine passati per l’oggetto line∼ che rende più graduale il passaggio da un valore all’altro eliminando 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~ Figura 88
Nella figura 88 è 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.
92
9.2 CONTROLLO DEL panning 87) 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. 89) osc~ 120
osc~ 1 expr~ if($v1 < 0.5, 1, 0) expr~ sqrt(1 - $v1) expr~ sqrt($v1)
*~
*~
dac~ Figura 89
9.2.1 S EGNALI BIPOLARI E UNIPOLARI
Nella patch in figura 88 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. 90). 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 102 si può
93
9.2 CONTROLLO DEL panning
Segnale bipolare e unipolare
a)
b)
Figura 90: L’ampiezza del segnale (a) oscilla fra valori positivi e negativi, mentre (b) è polarizzato nel campo positivo
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 103 è mostrato un segnale bipolare trasformato in un segnale unipolare tramite l’oggetto expr∼.
94
1.0 0.0 −1.0
−0.5
❘
1.0 0.5
➤
0.0 −0.5
−1.0
−1.0
−0.5
❘
b)
0.0
0.5
1.0
➤
−1.0
−0.5
❘
a)
0.0
0.5
0.5
➤
1.0
9.2 CONTROLLO DEL panning
Figura 91: la distanza massima fra l’ampiezza positiva e quella negativa del segnale bipolare (a) è doppia rispetto a quella del segnale (b)
95
9.2 CONTROLLO DEL panning
bipolare
osc~ 200
metro 100 tabwrite~ bipolare expr~ ($v1 * 0.5) + 0.5
unipolare tabwrite~ unipolare
dac~
Figura 92: lâ&#x20AC;&#x2122;oggetto exprâ&#x2C6;ź permette facilmente di effettuare le due operazioni sul segnale per trasformarlo trasformano da bipolare a unipolare
96
10 S I N T E S I A D D I T I VA , S I N T E S I TA B E L L A R E E SINTESI VETTORIALE
10.1 O PERATORI DI SEGNALE 10.1.1 expr∼
10.2 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 estremamente eterogenei. 10.2.1
SINTESI ADDITIVA A SPETTRO ARMONICO
10.2.2
SINTESI ADDITIVA A SPETTRO NON ARMONICO
10.2.3
SPETTRO FISSO
10.2.4
SPETTRO VARIABILE
10.3 S INTESI VETTORIALE 10.3.1
DISSOLVENZA INCROCIATA AUTOMATICA FRA DUE TABELLE
10.3.2
DISSOLVENZA INCROCIATA AUTOMATICA FRA PIÙ TABELLE
10.3.3
ALGORITMO DI SELEZIONE PER IL
10.3.4
CONTROLLO DEL
crossfading FRA TABELLE
crossfading ATTRAVERSO grid
97
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 complessi 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. Schematizzando, il suono sorgente prima di essere inviato agli altoparlanti passa attraverso un filtro, che realizza certe condizioni richieste (fig. 93).
segnale in entrata
filtro
segnale in uscita Figura 93: 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â&#x20AC;&#x2122;informazione sonora. In musica
98
11.1 LA SINTESI SOTTRATTIVA elettronica un rumore è una sequenza di oscillazioni casuali. Si distinguono vari tipi di rumori. Il rumore bianco è quello costituito da frequenza uniformemente distribuite, 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) 1 emesse ogni 44100 di secondo. Lo spettro del rumore bianco si presenta come in figura 94: le frequenze occupano tutta la banda audio. Rumore bianco
0
2000
4000
6000
8000
10000
12000
14000
16000
18000
20000
x
Figura 94: 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. 95). 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 impostata, successivamente produce delle bande secondarie larghe quanto la frequenza impostata ma di ampiezza sempre minore. L’esempio in figura (96) mostra lo spettro prodotto da rand∼ con frequenza 2500 hz.
99
11.1 LA SINTESI SOTTRATTIVA Rumore rosa
0
2000
4000
6000
8000
10000
12000
14000
16000
18000
20000
18000
20000
x
Figura 95: spettro del rumore rosa
Rumore band limited
0
2000
4000
6000
8000
10000
12000
14000
16000
x
Figura 96: spettro di rumore band-limited con frequenza di 2500 hz
Nella patch in figura 97 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.
100
11.2 I FILTRI
2500
0 choice $1
noise~ pink~
rand~
polygate~ 3 100
dac~ Figura 97: selezione del tipo di rumore tramite lâ&#x20AC;&#x2122;oggetto polygateâ&#x2C6;ź
11.2 I FILTRI I filtri sono algoritmi deputati a processare un segnale in entrata, attenuando determinate frequenze o esaltandone altre. In base al tipo di tagli sulle frequenze che effettuano se ne distinguono quattro tipi: - filtri passa-alto - filtri passa-basso - filtri passa-banda - filtri escludi-banda 11.2.1
FILTRI PASSA - ALTO
Un filtro passa-alto attenua le frequenze al di sotto di un valoresoglia, detto frequenza di taglio (cutoff frequency). 11.2.2
FILTRI PASSA - BASSO
11.2.3
FILTRI PASSA - BANDA
11.2.4
FILTRI ESCLUDI - BANDA
11.2.5
GLI ORDINI DEI FILTRI
101
12 M O U L A Z I O N E A D A N E L LO ( R M ) , 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 Modulation, 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 frequenze 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(α − β)] (12.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 100 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 101. Schematizzando: cos(α) ∗ cos( β) =
102
12.1 LA MODULAZIONE AD ANELLO
Modulazione ad anello
0
1000
2000
3000
x Figura 98: 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~ Figura 99: la patch di Pd che implementa la Modulazione ad anello dello spettro in figura 98
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 )
103
12.1 LA MODULAZIONE AD ANELLO - RM1 = (2000 + 500), (2000 − 500) - RM1 = 2500, 500 - RM2 = RM1 f ∗ γ f - 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~ Figura 100: doppia modulazione ad anello: 2 segnali vengono ringmodulati 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. Tecnicamente non c’è alcuna differenza con la modulazione vista qui sopra, ma si preferisce in queste circostanze parlare di suoni che vengono modificati con altri suoni: il suono da modulare viene definito Portante (Carrier), mentre il segnale che modula è detto Modulante (Modulator).
104
12.2 SEGNALI BIPOLARI E UNIPOLARI
Modulazione ad anello doppia
0
1000
2000
3000
4000
x Figura 101: lo spettro risultante dalla doppia modulazione ad anello
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 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 102 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 103 è mostrato un segnale bipolare trasformato in un segnale unipolare tramite l’oggetto expr∼.
105
1.0 0.0 −1.0 1.0 0.5
➤
0.0 −1.0
−1.0
−0.5
−0.5
❘
b)
0.0
0.5
1.0
➤
−1.0
−0.5
−0.5
❘
❘
a)
0.0
0.5
0.5
➤
1.0
12.3 SEGNALE DI CONTROLLO DELL’AMPIEZZA: IL TREMOLO
Figura 102: la distanza massima fra l’ampiezza positiva e quella negativa del segnale bipolare (a) è doppia rispetto a quella del segnale (b)
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 interferire con la frequenza del suono modulato. Inoltre una frequenza troppo alta non permetterebbe di percepire l’effetto tremolo desiderato. Tradizional-
106
12.3 SEGNALE DI CONTROLLO DELL’AMPIEZZA: IL TREMOLO bipolare
osc~ 200
metro 100 tabwrite~ bipolare expr~ ($v1 * 0.5) + 0.5
unipolare tabwrite~ unipolare
dac~
Figura 103: l’oggetto expr∼ permette facilmente di effettuare le due operazioni sul segnale per trasformarlo trasformano da bipolare a unipolare
mente 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 interattivamente 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 105 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
107
12.3 SEGNALE DI CONTROLLO DELLâ&#x20AC;&#x2122;AMPIEZZA: IL TREMOLO osc~ 800
controllo_tremolo 2 osc~ 1 expr~ ($v1 * 0.5) + 0.5
*~ $1 20 line~ *~
dac~
Figura 104: con la number box si può aumentare o diminuire la frequenza del tremolo
Tremolo
a)
b)
c)
Figura 105: il segnale (a) viene moltiplicato per il segnale (b) generando il tremolo rappresentato in (c)
108
12.4 LA MODULAZIONE D’AMPIEZZA Tremolo controllato in ampiezza
a)
b)
c)
Figura 106: il segnale (b) varia in ampiezza generando una variazione dell’ampiezza di (c)
in ampiezza, in modo da poter decidere anche l’escursione del tremolo. La figura 106 mostra proprio questa situazione. L’onda (b) varia l’ampiezza producendo in (c) un cambiamento graduale dell’entità del tremolo. In figura 107 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 104 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. 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 quel-
109
12.4 LA MODULAZIONE D’AMPIEZZA osc~ 1600 frequenza ampiezza
1
37 osc~ 1
/ 100
expr~ ($v1 * $f2) + (1 - $f2) wave
*~
$1 20 line~ *~ metro 25 dac~
tabwrite~ wave
Figura 107: con la number box a destra si può controllare l’ampiezza del tremolo
lo bipolare. Risultato: La modulazione d’ampiezza produce un suono con uno spettro in cui è presente la frequenza Portante e tutte le frequenza somma e differenza 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 ( α )
110
12.4 LA MODULAZIONE D’AMPIEZZA Rispetto alla Modulazione ad anello, nello spettro è quindi presente anche il segnale Portante. In figura 108 viene mostrato lo spettro di una modulazione 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 Modulazione d’ampiezza semplice
0
500
1000
1500
2000
x Figura 108: Il segnale portante ha frequenza di 800 hz, mentre il modulante ha frequenza di 160 hz
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 portante e della modulante e in più le frequenze della portante. La patch in figura 111 mostra una doppia modulazione d’ampiezza. La portante di 1500 hz viene modulata con un segnale di 500 hz. Il risultato di tale modulazione è 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 =
111
12.4 LA MODULAZIONE D’AMPIEZZA osc~ 800
osc~ 160 expr~ ($v1 * 0.5) + 0.5
*~
$1 20 line~ *~
dac~ Figura 109: la patch che produce lo spettro della figura precedente
(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 111. 12.4.1
L’ INDICE DI MODULAZIONE
La patch in figura 109 genera una semplice modulazione d’ampiezza dove la Portante e le frequenze laterali hanno la stessa ampiezza. Oltretutto impostare a zero la frequenza o l’ampiezza della Modulante porterebbe a zero anche l’ampiezza della Portante, poiché il segnale Portante sarebbe moltiplicato per zero. Attraverso un indice di modulazione è possibile controllare il rapporto fra l’ampiezza della Portante e quella della Modulante.
112
12.4 LA MODULAZIONE D’AMPIEZZA osc~ 1500 osc~ 500 expr~ ($v1 * 0.5) + 0.5 osc~ 300 *~
*~
expr~ ($v1 * 0.5) + 0.5
$1 20 line~
*~
dac~ Figura 110: la patch realizza una modulazione d’ampiezza con due modulanti
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 112 c’è lo spettro di una modulazione con Portante a 800 hz e Modulante a 160 hz. Nella figura 113 c’è la relativa patch di Pd.
113
12.4 LA MODULAZIONE Dâ&#x20AC;&#x2122;AMPIEZZA
Modulazione di ampiezza con 2 modulanti
0
1000
2000
3000
x Figura 111: la patch che produce lo spettro della figura precedente
Indice di modulazione 0.25
0
500
1000
1500
x Figura 112: spettro di modulazione di ampiezza con indice di modulazione pari a 0.25
114
12.4 LA MODULAZIONE D’AMPIEZZA
osc~ 800 osc~ 160 expr~ ($v1 * 0.5) + 0.5
$1 20 line~
expr~ ($v1 * $v2) + (1 - $v2)
*~
$1 20 line~ *~
dac~ Figura 113: la slider verticale a destra controlla l’indice di modulazione, con range da 0 a 1
115
13 V I B R ATO E M O D U L A Z I O N E D I F R E Q U E N Z A ( F M )
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 frequenza 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 sig~
40 *~
+~
osc~
metro 100 dac~
tabwrite~ vibrato
Figura 114
116
13.2 MODULAZIONE DI FREQUENZA Nella patch in figura 114 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 frequenza 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: I =
D 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 deviazione di picco, più numerose le componenti della portante modulata in frequenza. In figura 115 è mostrata una patch per la 1 R. Bianchini, A. Cipriani, Il Suono Virtuale, ed. Contempo, pag. 244
117
13.2 MODULAZIONE DI FREQUENZA modulazione di frequenza semplice. Fa uso di tre subpatch che esaminiamo una alla volta.
pd modulante freq
indice
200
1000 10
Deviazione 2000
pd portante freq 4000 pd uscita
dac~ Figura 115: la patch per la modulazione di frequenza semplice
In figura 116 è raffigurata la subpatch per la portante. L’inlet riceve il segnale prodotto dalla modulante, che viene sommato alla frequenza della portante, che si può impostare con la number box in alto. In figura 117 si può osservare che la number box a sinistra imposta la frequenza dell’oscillatore modulante. Tale frequenza viene
118
13.2 MODULAZIONE DI FREQUENZA
freq 0 inlet~
+~ osc~ outlet~ Figura 116: la subpatch per il segnale portante
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 in uscita dall’outlet entra nell’inlet della Portante. Sulla patch per l’uscita (fig. 118) 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 119 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 120 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 continui. Non ci siamo occupati di definire un evento nel dominio del tempo, che fosse provvisto di un inizio e di una fine,
119
13.2 MODULAZIONE DI FREQUENZA
freq
indice
200
1000 10
Deviazione 2000 t b f / 100 osc~ 200 $1 20
$1 20
line~
line~
*
*~
*~ outlet~
Figura 117: la subpatch per il segnale modulante
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 assume rispetto al tempo. In figura 121 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
120
13.2 MODULAZIONE DI FREQUENZA
$1 20 inlet~
line~
*~ outlet~
Figura 118: la subpatch per l’uscita
Spettro FM indice 0.1
0
1000
2000
3000
4000
5000
6000
7000
8000
x
Figura 119: FM con frequenza portante di 4000 hz, modulante di 200 hz e indice di modulazione 0.1
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 un esempio tipico di
121
13.2 MODULAZIONE DI FREQUENZA Spettro FM indice 10
0
1000
2000
3000
4000
5000
6000
7000
8000
x
Figura 120: FM con frequenza portante di 4000 hz, modulante di 200 hz e indice di modulazione 10
ampiezza
Inviluppo di tromba
tempo Figura 121
inviluppo è quello mostrato in figura 122(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. 123). Nella prossima sezione faremo uso di generatori di inviluppo
122
13.2 MODULAZIONE DI FREQUENZA
a)
b)
c)
Figura 122: 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 istantanee di (a) vengono moltiplicate per i relativi valori di (b), producendo (c)
nella modulazione di frequenza. 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 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 2
123
13.3 PORTANTI MULTIPLE
Figura 123: l’oggetto envgen
con una punta massima di 25 e un altro inviluppo per l’ampiezza del suono. In figura 124 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. 125. La subpatch envamp invece memorizza i dati del’altro envgen e li spedisce a line senza alcun riscalamento. Infine in figura 127 c’è il sequencer per la generazione dei bang per innescare 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 contatore 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.2.3
ALGORITMO PER IL CONTROLLO
13.3 P ORTANTI MULTIPLE 13.4 M ODULANTI MULTIPLE
124
random DEI PARAMETRI
13.4 MODULANTI MULTIPLE
r dur r trig osc~ 55 duration $1 dump
r envindex
*~ 55 *~ +~ 80 osc~ pd indexenv loadbang 200
r dur r trig duration $1 dump
r envamp
200 *~
s dur
dac~
pd envamp pd seqz START
SPEED 150
Figura 124: la patch per lâ&#x20AC;&#x2122;FM semplice di Chowning
125
13.4 MODULANTI MULTIPLE
inlet
inlet
prepend set
unpack f f
loadbang
* 25 pack f f
1 16 0 184 0
line~ 0 5
s envindex
outlet~
Figura 125: 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â&#x20AC;&#x2122;help dellâ&#x20AC;&#x2122;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
Figura 126: la subpatch envamp
126
13.4 MODULANTI MULTIPLE
r trig START
SPEED 150
b 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
Figura 127: la subpatch seqz
127
14 SINTESI PER DISTORSIONE NON LINEARE (DNL)
14.1 A NCORA SULLE TABELLE 14.2 T EORIA DELLA SINTESI PER DISTORSIONE NON LINEARE 14.3 S INTESI PER DISTORSIONE NON LINEARE
128
15 INTRODUZIONE ALLA SINTESI GRANULARE
15.1 T EORIA DELLA SINTESI GRANULARE 15.1.1 PANORAMICA DEI TIPI DI SINTESI GRANULARE
15.2 A LGORITMO PER LA SINTESI Pulsar
129
16 A LT R E A P P L I C A Z I O N I D I P U R E D ATA
16.1 GEM E IL VIDEO 16.1.1
UN ESEMPIO CON
GEM
16.2 A RDUINO 16.2.1 pduino
16.3 I L PROTOCOLLO osc 16.3.1 netsend E netreceive
16.4 I L Live coding 16.4.1
SUONARE IN RETE : oggcast∼
130
CONCLUSIONE
131
INDICE ANALITICO
object box, 17 object box, 16, 17 print, 16
132