Settaggi, oscillatori e monitors¶
Indice¶
import os
SuperCollider ¶
SuperCollider è formato da due applicazioni che operano in parallelo
Se vogliamo leggere, generare o modificare segnali audio dobbiamo eseguire il boot del Server.
Boot info ¶
Quando eseguiamo il boot il Server si collega ai driver audio utilizzati in quel momento dal sistema operativo del computer.
Se invece vogliamo utilizzare una scheda audio esterna dobbiamo selezionarla dalle preferenze di sistema come per tutti gli altri software.
Quando effettuiamo il boot del Server compaiono nella Post window alcune informazioni che possono tornare utili:
- Il nome e un indirizzo IP che identifica il Server che stiamo accendendo. Attraverso questo indirizzo potremo inviare messaggi a quel Server specifico e non ad altri.
Booting server 'localhost' on address 127.0.0.1:57110.
- Il numero e i nomi dei devices (sia reali che virtuali) che abbiamo a disposizione per fare comunicare il Server con il mondo esterno.
Found 0 LADSPA plugins Number of Devices: 5 0 : "Microfono MacBook Air" 1 : "Altoparlanti MacBook Air" 2 : "Microsoft Teams Audio" 3 : "VB-Cable" 4 : "ZoomAudioD"
- Il device (tra quelli dell'elenco precedente) collegato al Server e quanti canali audio supporta sia per quanto riguarda i segnali in entrata che per quelli in uscita.
"Microfono MacBook Air" Input Device Streams: 1 0 channels 1 "Altoparlanti MacBook Air" Output Device Streams: 1 0 channels 2
- La Sample rate e il block size alla quale sta lavorando il Server in questione.
SC_AudioDriver: sample rate = 44100.000000, driver's block size = 512
- Alcuni messaggi di controllo che indicano lo stato delle comunicazioni tra Server e Client.
SuperCollider 3 server ready. Requested notification messages from server 'localhost' localhost: server process's maxLogins (1) matches with my options. localhost: keeping clientID (0) as confirmed by server process. Shared memory server interface initialized
Variabili globali, classi e messaggi ¶
Ci sono due Server di default.
Possiamo scegliere quale utilizzare.
s = Server.local; // Settiamo il Server locale
La lettera ___s___ è una variabile.
La parola ___Server___ è una classe.
La parola ___.local___ è un messaggio.
Cos’è una variabile?
Porzione di memoria del computer destinata a contenere dei dati (numeri, caratteri, audio files, synth, tabelle, array, etc.), suscettibili di modifica nel corso dell’esecuzione di un programma.
Per distinguere la singola porzione di memoria tra le tante, dobbiamo contrassegnarla con un nome (o etichetta o indirizzo).
La linea di codice nella cella precedente chiama con il nome 's' una porzione di memoria e la assegna al Server locale.
In SuperCollider esistono tre tipi di variabili:
- Globali $\rightarrow$ lettere minuscole.
- dichiarate generalmente all’inizio del file
- possiamo richiamarle in tutto il codice successivo.
- Ambientali. $\rightarrow$ lettera o parola preceduta dal simbolo tilde (~).
- Tutto lo script è considerato un ambiente di programmazione
- Sono valide all’interno di tutto quest’ambiente (currentEnvironment).
- Locali. $\rightarrow$ precedute dalla keyword var $\rightarrow$ incluse tra parentesi (tonde o graffe).
- Terminamo con ;
- Il valore assegnato vale eslusivamente all'interno delle parentesi (scope della varibile)
La parola Server è una classe ovvero uno stampino attraverso il quale possiamo costruire tante copie di un oggetto (istanze).
Agli oggetti possono essere inviati dei messaggi che assumono due funzionalità:
- definirne le caratteristiche.
- richedere di compiere un'azione.
Possiamo inviare messaggi agli oggetti separandoli con un punto.
In questo caso abbiamo definito il Server come 'locale' inviando il messaggio .local alla classe Server e ne abbiamo assegnato una copia (istanza) alla variabile 's' secondo una delle più comuni strutture sintattiche impiegate in SuperCollider.
// Nome_variabile assegnazione Oggetto.messaggio_a_oggetto
s = Server.local;
s.boot; // Invia un nuovo messaggio a Server.local
s.quit;
s.reboot;
Possiamo ora intuire a cosa servono le variabili: rendere il codice più leggibile e meno ridondante.
Senza l'utilizzo della variabile s avremmo dovuto scrivere.
Server.local.boot;
Server.local.quit;
Server.local.reboot;
Il codice sulla stessa linea viene eseguito da sinistra a destra:
- dichiara il Server
- lo definisce come locale
- lo accende, spegne, etc. ( richiesta di compiere un'azione ).
Impostazioni del Server ¶
Attraverso la sintassi appena illustrata possiamo impostare dal codice diversi parametri del Server.
Definire quale Server utilizzare nello script corrente.
s = Server.internal;
s = Server.local;
La lettera s è assegnata di default al Server locale.
Se vogliamo modificare il Server di default che sarà assegnato alla variabile globale s in assenza di ulteriori messaggi.
Server.default = Server.internal;
Server.default = Server.local;
Principali messaggi che possiamo inviare al Server in uso.
s = Server.local;
s.boot; // Boot del Server
s.quit; // Chiude il Server
s.reboot; // Chiude e riapre il Server
s.waitForBoot({...}) // Accende il Server e terminato il booting esegue il codice successivo tra le parentesi
s.freeAll; // Libera tutti i nodi nel Server
s.volume = 0; // Setta il voume in uscita (in dB)
s.mute; // Mute del Server
s.unmute; // Unmute
In assenza di indicazioni SuperCollider riceve e invia tutti i segnali audio ai driver selezionati nel sistema operativo.
Possiamo modificare questa scelta dal codice attraverso le ___ServerOptions___.
Otteniamo un elenco di dispositivi connessi al computer.
ServerOptions.devices;
ServerOptions.inDevices;
ServerOptions.outDevices;
Selezioniamo quello da utilizzare.
s = Server.local;
o = s.options;
o.device; // riporta il device in uso
o.device = "Soundflower (2ch)"; // seleziona il device specificando il nome
o.device_("Soundflower (2ch)"); // altra sintassi...
s.reboot; // Se già acceso dobbiamo spegnere e riaccendere...
o.device = nil; // 'nil' specifica i driver in uso dal sistema
s.reboot;
Dispositivi differenti per i segnali in entrata e quelli in uscita.
o.inDevice = "Built-in Microph";
o.outDevice = "Soundflower (2ch)";
s.reboot;
Modificare il numero di canali.
o.numOutputBusChannels.postln; // riporta l'informazione nella post window
o.numOutputBusChannels = 8; // modifica i settings
o.numOutputBusChannels_(8); // altra sintassi...
o.numInputBusChannels.postln; // riporta
o.numInputBusChannels = 8; // modifica
o.numInputBusChannels(8); // altra sintassi...
s.reboot;
Modificare rata di campionamento e block size.
o.sampleRate; // riporta
o.sampleRate = 44100; // modifica
o.sampleRate_(44100);
o.blockSize; // riporta
o.blockSize = 64; // modifica
o.blockSize_(64);
s.reboot;
UGens ¶
Ora che sappiamo accendere il Server di SuperCollider e ricevere o inviare alle porte del computer segnali audio vediamo come generarli o modificarli utilizzando una tipologia di oggetti chiamati UGens o Unit Generator.
Le UGens sono particolari classi ottimizzate per la generazione o modifica di segnali audio.
Le UGens 'vivono' nel Server.
Come tutte le classi cominciano sempre con una lettera maiuscola e di default sono colorate di blu.
Possono ricevere solo tre messaggi che ne definiscono la rata ovvero quanti valori devono generare o modificare nel tempo (azioni da compiere).
- UGen.ar - audio rate - Genera o modifica tanti valori quanto la sample rate.
- UGen.kr - control rate - Genera o modifica tanti valori quanto la sample rate / block size.
- UGen.ir - inizialization rate - Genera o modifica un solo valore nel momento in cui viene creata.
Nella figura seguente lo stesso segnale generato ad audio rate (sopra) e a control rate (sotto)
{[SinOsc.ar,SinOsc.kr]}.plot(1/50, bounds:1000@500);
I segnali a audio rate possono sia essere collegati agli inputs (adc) o outputs (dac) che utilizzati come segnali di controllo dei parametri di altre UGens mentre i segnali a control rate non possono essere collegati agli inputs e agli outputs.
Mentre i tre messaggi precedenti definiscono quanti valori vengono generati nel tempo i nomi delle specifiche UGen indicano quale tipo di relazione intercorre fra i valori generati (forma d'onda).
Possiamo ottenere un elenco di tutte le UGens andando nella finestra degli Help files e cliccando prima su Browse e poi su UGens.

Tutti e tre i metodi invocabili sulle UGen possiedono degli argomenti che specificano i valori di alcuni parametri del segnale da generare o modificare come ad esempio frequenza, ampiezza o altro.
Gli argomenti sono specificati all'interno di parentesi tonde e sono differenti per ogni UGen sulla quale sono invocati i metodi.
Per conoscere quali sono gli argomenti di una specifica UGen dobbiamo richiamarne l'Help file.
Come esempio osserviamo quelli di SinOsc che è un oscillatore sinusoidale.

Il primo specifica la frequenza in Hertz.
(
{[SinOsc.ar(1320),
SinOsc.ar(880),
SinOsc.ar(440)]
}.plot(minval:-1,maxval:1)
)
Il secondo specifica la fase iniziale in radianti tra -1 e 1.
(
{[SinOsc.ar(440,0.0),
SinOsc.ar(440,0.5),
SinOsc.ar(440,1.0)]
}.plot(minval:-1,maxval:1)
)
Il terzo specifica un fattore di moltiplicazione dei valori in uscita (usualmente compresi tra -1.0 e + 1.0).
(
{[SinOsc.ar(440,0,1.0),
SinOsc.ar(440,0,0.5),
SinOsc.ar(440,0,0.2)]
}.plot(minval:-1,maxval:1)
)
Il quarto specifica un valore da sommare ai valori in uscita.
(
{[SinOsc.ar(440,0,1.0),
SinOsc.ar(440,0,0.5),
SinOsc.ar(440,0,0.2)]
}.plot(minval:-1,maxval:1)
)
Questi ultimi due argomenti (mul e add) sono compresi in quasi tutte le UGens e impiegati di prassi per riscalare il range in uscita.
Non è necessario specificare tutti gli argomenti.
Quelli non indicati assumeranno il valore di default che possiamo trovare nell'help file.
Possiamo utilizzare due sintassi differenti.
- La prima sottointende le keywords e non possiamo saltare posizioni da sinistra a destra.
SinOsc.ar(440,0,0.3);
- La seconda utilizza le keywords e possiamo sia saltare posizioni che cambiarne l'ordine.
SinOsc.ar(mul:0.7, freq:500);
Nel proseguio di questo scritto ci soffermeremo sulle caratteristiche delle singole UGens, per ora possiamo curiosare richiamando l'Help file di alcune tra quelle in elenco.
Monitors ¶
I monitors che riguardano l'audio sono di tre tipi:
- Uditivo - otteniamo informazioni sul codice ascoltando il risultato sonoro.
- Grafico - visualizziamo la forma d'onda (oscillogramma), lo spettro (spettrogramma) o l'intensità (meters) del segnale.
- Numerico - visualizziamo i valori dei singoli campioni o meglio di campioni estratti dallo stream numerico in istanti definiti (sottocampionamento).
In SuperCollider possiamo monitorare:
- l'attività computazionale.
- i segnali audio in ingresso o in uscita dal Server.
- i segnali audio in uscita dalle UGens sia ad audio rate che a control rate.
Attività computazionale
Abbiamo due tipologie di monitor numerici:
1 - Leggere le informazioni nell'IDE (in basso a destra).

- 0.02%: utilizzo medio della CPU.
- 0.06%: utilizzo di picco della CPU.
- 0u: numero di UGens attive nel Server.
- 0s: numero di Synths attivi nel Server.
- 2g: numero di Groups attivi nel Server.
- 94g: numero di SynthDef attive nel Server.
- 0.0dB: Master gain del Server.
- M: Mute (o meno).
Cliccando sui numeri appare la seguente finestra dove possiamo attivare o disattivare diversi comandi.

2 - Ottenere i valori invocando metodi nel codice.
s.status; // Riporta il nome del Server in uso
s.avgCPU; // Riporta l'utilizzo medio della CPU
s.peakCPU; // Riporta l'utilizzo di picco della CPU
s.numUGens; // Riporta il numero di UGens
s.numSynths; // Riporta il numero di Synths
s.numGroups; // Riporta il numero di Gruppi
s.numSynthDefs; // Riporta il numero di SynthDefs
s.volume; // Riporta il volume massimo in uscita (dB)
s.mute; // Muting
s.unmute; // Toglie il Mute
Una delle ragioni di poter ottenere queste informazioni dal codice sta nel fatto che potremmo utilizzarle come
- valori di controllo di una qualche tecnica di sintesi o di elaborazione del segnale
- vsualizzarli in un'interfaccia grafica (GUI) per un monitoraggio visivo personalizzato.
Segnali in ingresso e uscita dal Server
Richiamiamo interfacce grafiche (GUI) dedicate.
s.meter; // Visualizza segnali in input e ouput
s.scope(2); // Oscilloscopio del master out (il numero di canali si accorda
// con quello specificato nelle ServerOption oppure possiamo spe-
// cificarlo come argomento)
s.freqscope; // Spettroscopio del master out (monofonico, possiamo scegliere
// quale canale (Bus) visualizzare specificandone l'ID nel box
// a destra. Possiamo inoltre specificare se la visualizzazione
// deve essere lineare o logaritmica (di default) e anche il li-
// mite inferiore in dB -(96 di default)
{Pan2.ar(Mix(SinOsc.ar(Array.rand(20,200,5000),0,0.1)),0.3)}.play // Test
Segnali in uscita dalle UGens
Uditivo
Un modo veloce per far suonare e monitorare attraverso l'ascolto una o più UGens consiste nell'includerla tra parentesi graffe e invocare il metodo ___.play___.
E' un'abbreviazione sintattica che possiamo utilizzare esclusivamente per prototipare velocemente algoritmi di sintesi.
{SinOsc.ar}.play;
{SinOsc.ar + WhiteNoise.ar}.play;
Grafico
Per avere un monitoraggio visivo della forma d'onda (oscillogramma) del segnale in uscita di una specifica UGen (o da un network di UGens) possiamo invocare il metodo ___.scope___ che sostituisce ___play___.
{Saw.ar}.scope;
{SinOsc.ar(LFNoise0.kr(15,1000,2000))}.scope;
Possiamo utilizzare i diversi metodi in contemporanea.
(
{
SinOsc.ar(2000 + (1000 * LFNoise0.kr(5).scope(\pitch)) // Scope segnale di controllo
).scope(\sine) // Scope segnale audio
}.play; // Monitor uditivo
s.scope; // Scope del Server
)
Due considerazioni.
La prima consiste nel fatto che l'argomento di .scope() è il nome che vogliamo dare alla finestra grafica.
La seconda riguarda il colore che differenzia lo scoping dei segnali a audio rate (gialli) da quelli a control rate (verdi).
Possiamo anche visualizzare in un plot i valori dell'output di una UGen invocando l'omonimo metodo.
Nell'esempio seguente sono illustrati i principali argomenti per questo tipo di plot.
{Pulse.ar}.plot;
{Pulse.ar + Saw.ar}.plot(duration: 0.01 ); // Durata della finestra in secondi
{Pulse.ar * Saw.ar}.plot(bounds: Rect(0,0,500,100)); // Dimensioni grafiche finestra
{Pulse.ar * PinkNoise.ar}.plot(bounds: 500@100); // Abbreviazione
{Pulse.ar + WhiteNoise.kr}.plot(minval: -2, maxval: 2); // Minimo e massimo asse y
Numerico
Infine per un monitoraggio numerico dei valori dei singoli campioni possiamo utilizzare il metodo ___.poll___ invocato direttamente su una UGen.
Questo metodo stampa semplicemente nella Post window i valori in uscita.
L'argomento è il numero di campioni per secondo da stampare (sottocampionamento).
Questo metodo serve solo per monitorare, non possiamo assegnare i singoli valori ad una variabile per poi riutilizzarli all'interno del codice.
{SinOsc.ar.poll(1)}.play;
{SinOsc.ar(MouseX.kr(40,10000,1).poll(10), 0, 0.1) }.play;
Help files ¶
Gli Help files delle UGens sono principalmente divisi in tre sezioni.
la prima contiene informazioni generali sull'oggetto e suggerimenti su UGens simili.
la seconda contiene informazioni riguardo ai messaggi (metodi) che possiamo invocare sulla UGen e sui loro argomenti. Sono divisi in metodi di classe e metodi d'istanza.
la terza contiene esempi di utilizzo della UGen che possono essere eseguiti direttamente in loco.
PD ¶
Preferenze ¶
I settaggi audio in Pure Data possno essere controllati dal menù Preferenze $\rightarrow$ preferenze audio.

Ordine esecuzione¶
In SC il codice viene eseguito dall'alto verso il basso, da sinistra a destra, linea dopo linea.
In PD è più complicato ovvero segue l'ordine con cui abbiamo collegato gli oggetti.

Totalmente ingestibile.
Conviene sempre specificare lórdina con l'oggetto trigger (abbreviato con t)
Se un object box ha più di un outlet l'ordine di uscita dei valori va anch'esso da destra a sinistra.

os.system('open 3_settaggi/patch/3.1.pd')
0
Se un object box ha più di un inlet:
il primo a sinistra $\rightarrow$ inlet caldo
- memorizza il dato in ingresso,
- esegue l'operazione,
- manda il risultato in uscita dall'outlet.
tutti quelli più a destra del primo $\rightarrow$ inlet freddi
- memorizzano il il dato in ingresso in quella posizione
- non mandano il risultato in uscita.
Se un singolo patch cord entra in più inlets l'ordine è sempre da destra a sinistra.

os.system('open 3_settaggi/patch/3.2.pd')
0
adc~ e dac~¶
Per recuperare segnali audio in ingresso possiamo utilizzare l'oggetto ___adc~___ che accetta come argomenti il numero di canale(i) al quale collegarsi.
Per inviare segnali audio in uscita possiamo utilizzare l'oggetto ___dac~___ che accetta come argomenti il numero di canale(i) al quale collegarsi.

os.system('open 3_settaggi/patch/3.3.pd')
0
Oscillatori librerie e monitors¶
Oggetti audio che generano segnali (oscillatori) e altri che li modificano.

os.system('open 3_settaggi/patch/3.4.pd')
0
Caricare librerie esterne $\rightarrow$ Aiuto $\rightarrow$ trova external
Compare la finestra deken

Carichiamo due librerie utili:
- cyclone
- else
Tasto destro nel patch e compare un menù con tutti gli oggettu a disposizione.
Potrebbe essere necessario specificare di includerle al riavvio dal pannello Preferenze
I segnali possono essere monitorati principalmente attraverso tre GUI.
- meter~ - per visualizzare la dinamica.
- scope~ - un oscilloscopio per visualizzare la forma d'onda.
- spectrograph~ - uno spettroscopio per visualizzare lo spettro.
Accettano i segnali da monitorare negli inlet di sinistra.

os.system('open 3_settaggi/patch/3.5.pd')
0
Help files¶
Veri e propri patch strutturalmente simili a quelli di SuperCollider.
- selezionare l'oggetto
- $\rightarrow$ tasto destro $\rightarrow$ Aiuto
