Campioni di tempo
I secondi vengono definiti prendendo come campione di tempo il periodo di oscillazione delle onde luminose emesse da un atomo di cesio 133 in una particolare transizione atomica.   YouMath
Campionamento
Come abbiamo già osservato nel paragrafo dedicato il suono è generato da piccole variazioni nella pressione atmosferica che si propagano nello spazio e nel tempo e fino alla fine degli anni '40 del secolo scorso poteva essere trasdotto solo dall'apparato uditivo umano oppure da apparati microfonici utilizzati per le trasmissioni radio dei segnali ma non poteva essere memorizzato su alcun tipo di supporto dedicato a una diffusione culturale di massa. In realtà esistevano già diverse tecnologie dedicate alla memorizzazione delle onde sonore ma o erano di scarsa qualità e diffusione come i fonografi e i grammofoni o erano utilizzate solo a livello sperimentale oppure erano dedicate alle comunicazioni tra apparati militari.
Il solo veicolo di trasmissione di eventi sonori a fini musicali restava la partitura che doveva essere interpretata da un esecutore umano e, se qualcuno voleva ascoltare un determinato brano doveva recarsi in un teatro o in una sala da concerti che lo aveva in cartellone. Sottolineiamo il fatto che l'esecuzione (così come l'ascolto) era unica e non ripetibile e la sola memoria in grado di conservare i suoni era quella umana. Tutto questo fino al 1948, anno in cui negli Stati Uniti la Columbia ha brevettato il primo disco in vinile a 33 giri nei formati da 25 e da 30 cm e dove la forma d'onda (così come avveniva in precedenza con i dischi a 78 giri) era stampata in microsolchi che si sviluppavano a spirale lungo la superfice del disco e che erano letti da una testina del giradichi.
L'anno successivo (1949) viene inoltre introdotto sul mercato un altro tipo di supporto dedicato alla conservazione e riproduzione del suono: i primi registratori a nastro magnetico avvolto su bobine mentre successivamente nel 1964 la Philips commercializza in Europa la musicassetta a quattro tracce. E' cominciata l'era della fruizione musicale (e culturale) di massa che dopo centinaia di anni ha modificato profondamente e definitivamente il nostro rapporto con il mondo dei suoni.
Tutti i supporti e i sistemi di memorizzazione delle onde sonore appena esposti (oltre ad altri che non ho ritenuto opportuno citare in questa sede) appartengono al mondo dell'audio analogico in quanto l'informazione o meglio la rappresentazione dell'onda sonora avviene in modo continuo e analogo rispetto alle originali variazioni di pressione atmosferica. Questo perchè i dispositivi di registrazione analogici (trasduttori o microfoni) trasformano le variazioni di pressione atmosferica in variazioni di voltaggio di un segnale elettrico, che possono essere memorizzate su supporti meccanici (dischi in in vinile) o elettromagnetici (nastri magnetici) per poi essere eventualmente riprodotte una o più volte in momenti successivi. Questa oltre che essere stata una epocale rivoluzione tecnologica ha influito enormemente anche sulla diffusione musicale nella società, sui ruoli della musica all'interno della stessa e sullo sviluppo dei linguaggi strettamente legati alle arti sonore o musicali.
Nel 1971 comincia una nuova rivoluzione che però questa volta è strettamente tecnica (sotto un punto di vista culturale e sociale non fa
altro che amplificare e velocizzare il porcesso di diffusione globale delle informazioni già in atto): la nascita dell'audio digitale. In
quell'anno infatti i laboratori di ricerca della NHK (la radio televisione pubblica giapponese) realizzano il primo registratore audio digitale che,
attraverso la tecnica della PCM (Pulse Code Modulation)
brevettata dal britannico A.Reeves nel 1937 permette una codifica binaria del suono mentre nel 1976 Thomas Stockhham, docente del MIT, realizza la
prima registrazione audio digitale su nastro magnetico presso il Teatro dell'Opera di Santa Fe che porterà infine all'introduzione sul mercato nel
1982 da parte di Philips e Sony dei CD (Compact Disc) ottici con lettore al laser tuttora di uso comune (anche se è già in atto il loro declino
tecnologico verso altri tipi di condivisione musicale digitale). Ai nostri giorni ormai quasi tutte le informazioni legata all'audio (e non solo) sono digitali,
ma in cosa differisce l'audio digitale rispetto all'audio analogico? Fondamentalmente nel fatto che nel primo abbiamo una rappresentazione
continua di un segnale mentre nel secondo una rappresentazione discreta, ovvero si effettuano misurazioni del voltaggio che scorre
in un cavo proveniente da un microfono (rappresentazione continua) a istanti di tempo separati da un tempo delta costante come illustrato nel prossimo paragrafo.
Catena elettroacustica digitale
Possiamo pensare l'audio digitale come un prolungamento della catena elettroacustica analogica che abbiamo già incontrato:
Il processo di campionamento consiste nel misurare a precisi istanti di tempo separati tra loro da un tempo delta costante chiamato periodo di campionamento l'ampiezza istantanea del segnale audio analogico espressa sotto forma di tensione elettrica. La singola misura è chiamata campione (sample) e dopo aver subito un processo di quantizzazione produce una sequenza di parole binarie che corrispondono all’andamento del segnale. Osserviamo nel dettaglio il processo appena illustrato analizzando i diversi tipi di segnale.
Segnale analogico
I microfoni trasducono l'energia meccanica propria delle onde sonore in energia elettrica utilizzando diverse tecnologie (induzione elettromagnetica, induzione elettrostatica o piezoelettricità). L'energia elettrica generata (corrente alternata) scorre nel cavo collegato al microfono e il suo andamento segue in modo analogo l'andamento delle variazioni di pressione originali trasportando l'informazione attraverso tutti i dispositivi connessi tra loro all'interno di una catena elettroacustica.
Questo tipo di segnale è continuo sia nel tempo che in ampiezza.
Segnale campionato
Abbiamo affermato che campionare un segnale significa misurarne l'ampiezza (y) a ogni periodo di campionamento ottenendo un segnale discreto nel tempo e continuo in ampiezza:
A questo punto però ci troviamo di fronte ad una questione: ogni quanto campionare il segnale? Teoricamente possiamo affermare che più è breve il periodo di campionamento minore sarà la perdita di informazioni tra un campione e il successivo ottenendo un segnale digitale più simile all’originale fino al limite ideale (periodo infinitamente piccolo) in cui il segnale analogico e quello campionato coincidono.
Praticamente però ci sono limiti tecnologici nella costruzione dei convertitori ADC che non ci permettono di arrivare a periodi così brevi. Dobbiamo allora partire dal presupposto che i campioni devono essere prelevati con velocità dipendente dalla variazione del segnale e tale velocità dipende dalla componente armonica con frequenza più alta che sarà quella che determina il periodo di campionamento.
Le frequenze dei parziali di uno spettro sono espresse in Hertz ovvero in cicli per secondo (cps), uniformiamo allora l'unità di misura e sostituiamo il periodo di campionamento con la rata di campionamento (Sample rate o sr o Audio rate) che è espressa anch'essa in Hertz e ci dice quanti campioni sono misurati in un secondo. Quanto più alta sarà la frequenza di campionamento, tanto più accurata sarà la descrizione del segnale. Ma torniamo alla domanda iniziale: qual è il valore minimo della frequenza di campionamento? e ancora: basta farla coincidere con la frequenza del parziale più alto presente nello spettro del suono da campionare? No. Sono necessari almeno due campioni per periodo del segnale o meglio: la frequenza di campionamento deve essere almeno il doppio della frequenza massima presente nello spettro del segnale (frequenza di Nyquist).
L'enunciato appena esposto è desunto dal Teorema di Nyquist-Shannon e se non adottato come regola oltre che ad una rappresentazione imprecisa del segnale porta alla generazione di errori nel segnale durante la rilettura dei campioni. Questo tipo di errori è dato dal fenomeno dell'aliasing o foldover. Ma in cosa consiste questo fenomeno? Come possimo osservare nelle figure seguenti se la frequenza di campionamento è troppo bassa le misure rilevate possono descrivere una frequenza più bassa di quella reale:
Sarà poi questa frequenza (chiamata frequenza alias) a essere riprodotta nel momento in cui andiamo a rileggere in modo sequenziale i campioni. Possiamo dunque affermare che tutte le frequenze al di sopra della frequenza di Nyquist (foldover) generano frequenze alias non presenti nel segnale originale e che sono al di sotto di tale soglia.
Questo fenomeno genera modifiche anche importanti a livello timbrico e le possibili soluzioni sono due:
Utilizzare la più alta frequenza di campionamento possibile innalzando di fatto la frequenza di Nyquist oltre la soglia dell'udibilità umana (20.000Hz)
Inserire un filtro passa-basso (anti aliasing) sia prima del campionamento che dopo la rilettura (per compensare eventuali modifiche delle fasi operate dal filtro in ingresso)
La rata di campionamento dello standard CD è stata fissata nel 1982 a 44.100 Hz proprio perchè è il doppio della soglia di udibilità umana (20.000*2) più 4.100 Hz che compensano la pendenza di taglio del filtro passa-basso in ingresso. Ai giorni nostri quasi tutti gli hardware dedicati all'audio digitale possono arrivare a frequenze di campionamento a 48.000 e 96.000 Hz annullando di fatto qualsiasi problematica relativa alla perdita di informazioni tra campioni successivi e al fenomeno dell'aliasing.
Segnale quantizzato
La trasformazione dell'ampiezza di un segnale da continua a discreta prende il nome di quantizzazione. Ogni valore misurato dal processo di campionamento (ampiezza istantanea) deve essere associato a un nuovo valore compreso in un insieme discreto di livelli introducendo in questo modo una serie di imprecisioni chiamata errori di quantizzazione, poiché valori differenti nel segnale analogico possono essere approssimati sullo stesso livello, divenendo indistinguibili.
L'ambito di ampiezza che vogliamo rappresentare (range) si chiama Valore di Fondo Scala (VFS) e se per definizione è compreso tra +/- 1 nel momento in cui andiamo a misurare le differenze di tensione elettrica del segnale analogico è espresso in Volt e può assumere valori differenti. Ad esempio se il segnale che vogliamo misurare è compreso tra 5 e 20 Volt:
VFS = 20 - 5 = 15
Questo parametro ci serve per misurare l'errore massimo di quantizzazione (Emax) attraverso la formula seguente:
Emax = VFS/2Q
Dove Q è uguale al numero di livelli di quantizzazione. Così come nell'audio analogico possiamo dire che il segnale rappresentato è uguale al segnale originale sommato al rumore (fruscio) e possiamo rappresentare questo rapporto con il SNR (Signal to Noise Ratio) anche nell'audio digitale possiamo stimare la distorsione indotta dal processo di quantizzazione attraverso il calcolo del SQNR medio (Signal Quantization Noise Ratio medio):
SQNR = Q*(√3/2)
In deciBel:
SQNRdB = 10log10SQNR^2
Risulta a questo punto evidente come utilizzando un numero maggiore di "scalini" (Q) la quantizzazione sia più precisa e la distorsione minore, infatti un SQNR alto è sempre indice di maggiore qualità. Notiamo che il calcolo appena illustrato vale per un SQNR medio e a parità di errore di quantizzazione le ampiezze più piccole in valore assoluto sono distorte maggiormente (in proporzione) rispetto a quelle più grandi. Per ovviare a questo problema e al fatto che l'essere umano percepisce meglio le variazioni che interessano ampiezze basse sono state pensate due differenti tecniche di quantizzazione:
Uniforme o lineare dove il numero di livelli di quantizzazione è uguale dagli intervalli di ampiezza del segnale originale (intervalli equi-spaziati).
E' la tecnica standard utilizzata dai costruttori dei convertitori A/D e D/A.
Non uniforme o non lineare dove il numero di livelli di quantizzazione è diverso dagli intervalli di ampiezza del segnale originale ovvero c'è più precisione nel quantizzare certi intervalli e meno per altri (intervalli spaziati differentemente): le ampiezze deboli sono spaziate meno di quelle elevate slegando in questo modo l'SQNR dalla gamma dinamica.
Generalmente vengono assegnati i valori a regioni uniformi sulla scala logaritmica ottenendo in questo modo una maggiore qualità: con 8 "scalini" logaritmici possiamo ottenere la gamma dinamica di un quantizzatore lineare a 13/14 "scalini" ottenendo inoltre un risparmio di memoria sul supporto. I contro sono che un convertitore a 8 "scalini" logaritmico funziona meglio di un equivalente lineare alle ampiezze basse, ma peggio alle ampiezze elevate e risulta più complesso applcare le tecniche di elaborazione del segnale in quanto la somma di due segnali corrisponde al prodotto.
Segnale numerico
L'ampiezza di un segnale analogico espressa in Volt può essere rappresentata da un numero in un sistema decimale mentre l'ampiezza di un segnale digitale deve essere espressa attraverso un sistema binario in quanto tutti i sistemi digitali accettano solo due stati:
- 0 = circuito aperto = falso
- 1 = circuito chiuso = vero
Nel sistema binario i numeri sono espressi in parole di diversa lunghezza e ogni singolo elemento è chiamato cifra significativa o in termini informatici bit che significa binary digit. Il bit infatti è la più piccola unità d'informazione manipolabile da un calcolatore digitale ed è possibile rappresentare fisicamente questa informazione con un segnale elettrico o magnetico che se supera una determinata soglia corrisponde al valore 1. Appare ora evidente come gli"scalini" di cui parlavamo pocanzi corrispondano al numero di bit o soglie con i quali andiamo a rappresentare un valore di ampiezza. Con un bit possiamo dunque ottenere due soli valori: 0 e 1 mentre con due bit quattro valori diversi (22):
0 | 0 |
0 | 1 |
1 | 0 |
1 | 1 |
Con tre bit (23):
Valore binario | Valore decimale |
---|---|
000 | 0 |
001 | 1 |
010 | 2 |
011 | 3 |
100 | 4 |
101 | 5 |
110 | 6 |
111 | 7 |
E via dicendo, per un gruppo di n bit possiamo rappresentare 2n valori. Nell'immagine seguente possiamo visualizzare la differenza che intercorre tra una quantizzazione lineare a 3 bit (8 livelli) e una a 4 bit (16 livelli):
Infine facciamo un esempio della quantizzazione di un segnale analogico compreso tra +/- 5V con una profondità di 8 bit:
Valore di tensione | Valore binario |
---|---|
[-5.000, -4.961] | 00000000 |
[-4.961, -4.922] | 00000001 |
[-4.922, -4.883] | 00000010 |
[-4.883, -4.844] | 00000011 |
... | 00000100 |
... | ... |
... | ... |
... | 11111011 |
[+4,844, +4,883] | 11111100 |
[+4,883, +4,922] | 11111101 |
[+4,922, +4,961] | 11111110 |
[+4,961, +5,000] | 11111111 |
In questo caso abbiamo una precisione del segnale che è data da: 10/28 Volt = 10/256 Volt = 0,039 Volt e tutti i valori di tensione compresi in un intervallo di 0,039V saranno rappresentati dallo stesso valore.
In informatica ci sono unità di informazioni che sono caratterizzate dal numero di bit che le descrivono ad esempio il byte è composto da 8 bit e permette ad esempio di stoccare un carattere (char) o una cifra (int) compresa tra 0 (00000000) e 255 (11111111). Questo raggruppamento di numeri permette una migliore leggibilità come quando in base decimale raggruppiamo un numero a tre per poter distinguere le migliaia (il numero 1.256.245 è decisamente più leggibile che 1256245). Un'altra unità di informazione composta da 16 bit è chiamata parola (word) mentre un'informazione a 32 bit parola doppia (double word).
Dal Dicembre 1998 l'organismo internazionale IEC (International Electrotechnical Commission) ha standardizzato alcune unità di misura informatiche:
- Kilobite (KB) = 1000 byte (prima del 1998 era 210 = 1024 byte).
- Megabite (MB) = 1000 KB = 1.000.000 byte (prima del 1998 era 220 = 1024 KB = 1.048.576 byte).
- Gigabite (GB) = 1000 MB = 1.000.000.000 byte (prima del 1998 era 230 = 1024 MB = 1.073.741.824 byte).
- Terabite (TB) = 1000 GB = 1.000.000.000.000 byte (prima del 1998 era 240 = 1024 GB = 1.099.511.627.776 byte).
Conoscendo la frequenza di campionamento in Hertz (Fc), la profondità di quantizzazione in bit (N) e la durata del flusso audio in secondi (D) possiamo stabilire quanti bit abbiamo bisogno per memorizzare un segnale digitale monofonico non compresso:
Size = Fc * N * D
Il numero di bit compreso nell'unità di tempo (un secondo) si chiama bit rate e si misura in bps (bit per secondo).
bitrate = Fc * N
Qua sotto alcuni valori standard:
Supporto | Fc (Hz) | Bit | SQNR (dB) | Canali | Bit rate (KBps) |
---|---|---|---|---|---|
Telefono | 8.000 | 8 | 48 | 1 | 8.00 |
Radio AM | 11.025 | 8 | 48 | 1 | 11.05 |
Radio FM | 22.050 | 16 | 96 | 2 | 88.20 |
CD Audio | 44.100 | 16 | 96 | 2 | 176.40 |
DAT | 48.000 | 16 | 96 | 2 | 192.00 |
DVD Audio | 192.000 | 24 | 144 | 6 | 1200.00 |
SuperCollider
Server
Nella Parte di questo scritto dedicata ai Linguaggi del Tempo abbiamo accennato all'architettura di SuperCollider dicendo che è formato da due applicazioni distinte che operano in parallelo: Client (o Interpreter o SClang) e Server (o SC synth). Come abbiamo visto nel corso della stessa Parte il Client utilizza processi di scheduling (o controllo) dove, se non compiamo alcuna azione (come la valutazione del codice) o generiamo un qualche tipo di automazione (come nelle Routine e nei Task) il software non produce alcun valore nel tempo, mentre il Server è il motore di sintesi del suono di SuperCollider, dove possiamo leggere, produrre e modificare segnali audio digitali lavorando a una determinata rata di campionamento. In questa Parte approfondiremo le sue caratteristiche ed esploreremo le sue potenzialità. Azzardiamo infine un paragone musicale per chiarire ulteriormente la differenza tra Client e Server pensando a uno strumento ad arco come il violino. Il corpo dello strumento (che produce suono) può essere paragonato al Server mentre il Client può assumere al tempo stesso tre differenti funzioni in una: la partitura, l'archetto e il braccio dello strumentista che interpretando la prima muove il secondo. Da questo punto in poi per evitare errori di programmazione diventa fondamentale tenere sempre a mente questa separazione che è presente in tutti i software audio ma che in SuperCollider è informaticamente strutturale.
Boot info
Quando accendiamo (boot) il Server, SuperCollider riporta nella nella Post window alcune informazioni che ci possono tornare utili:
Un numero che definisce (indicizza) il Server che stiamo "accendendo" in quanto sullo stesso computer possono convivere più Servers contemporaneamente (ad esempio localhost e internal) e ognuno può essere "acceso" o "spento". Attraverso questo numero (indice o etichetta) inoltre possiamo inviare messaggi a quel singolo Server e non a tutti gli altri.
booting 57110
Il numero e i nomi dei devices (sia reali che virtuali) che abbiamo a disposizione per fare comunicare questo Server con il mondo esterno. Come vedremo in seguito dobbiamo necessariamente sceglierne uno (o più) tra quelli compresi in questo elenco.
Number of Devices: 5 0 : "Built-in Microph" 1 : "Built-in Input" 2 : "Built-in Output" 3 : "Soundflower (2ch)" 4 : "Soundflower (64ch)"
Come possimo notare anch'essi sono indicizzati con un numero al quale corrisponde il nome sotto forma di stringaIl device collegato a questo Server di default ovvero al momento del booting e quanti canali audio supporta. Nell'esempio seguente sono indicati i drivers interni di un computer Mac sia per quanto riguarda i segnali in entrata (ADC) che per quelli in uscita (DAC)
"Built-in Microph" Input Device Streams: 1 0 channels 2 "Built-in Output" Output Device Streams: 1 0 channels 2
L'indicazioneStreams: 1
significa che le informazioni di tutte e due i canali audio sono rappresentate con un solo flusso numerico.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
Sappiamo già cosa è la sample rate ma cosa significa block size?Detta in breve è il ritardo in campioni che intercorre tra il segnale in entrata e il segnale in uscita dal device utilizzato dal Server e a volte è chiamato buffer size o vector size. Ma perchè c'è questo ritardo? Approfondiamo. Abbiamo stabilito che un segnale audio digitale non è altro che un flusso o sequenza di numeri (numeric stream). Per modificare i parametri del suono (come ampiezza, frequenza, timbro, etc.) di un segnale rappresentato in questo modo dobbiamo dunque effettuare operazioni matematiche su questi numeri e queste devono obbligatoriamente precedere il valore che viene inviato all'output audio essendo quest'ultimo il risultato dell'operazione. Per questo motivo nella computazione di un segnale audio digitale abbiamo bisogno di un tempo parallelo al tempo reale chiamato tempo logico (logical time) che precederà sempre di almeno un campione (il tempo necessario alla computazione di eventuali operazioni matematiche) l'invio del valore di ampiezza istantanea al convertirore D/A.
Per aumentare l'efficienza computazionale del tempo logico molti software dedicati all'audio effettuano queste operazioni non su un campione per volta ma su blocchi (o pacchetti) di campioni memorizzati di volta in volta in buffer (memoria temporanea). Il numero di campioni contenuti in un pacchetto corrisponde al block size e generalmente anche al buffer size.
Alcuni messaggi di controllo che indicano lo stato delle comunicazioni tra Server e Client:
SuperCollider 3 server ready. Receiving notification messages from server localhost Shared memory server interface initialized
Settaggi
In SuperCollider ci possono essere diversi Servers su uno stesso computer che possono essere controllati da un solo interprete, così come un interprete che abita un computer può controllare in rete uno o più Servers che sono su altri computers. Abbiamo già visto che quando lanciamo l'applicazione SuperCollider crea automaticamente due Servers: localhost e internal. Successivamente possiamo selezionare uno o l'altro dal codice invocando i metodi omonimi sulla Classe Server:
s = Server.internal; s = Server.local;
La Classe Server è la rappresentazione nel Client dell'applicazione Server in quanto quest'ultima essendo indipendente, non necessita della prima e può essere programmata direttamente dal terminale del computer attraverso linee di comando UNIX. Il Client infatti assume la semplice funzione di tradurre il codice da noi programmato in comandi UNIX inviati all'applicazione Server attraverso il protocollo OSC.
Server.default
Quando lanciamo l'applicazione si aprono automaticamente i due Server appena illustrati ma se effettuiamo il boot senza specificare nulla, ad esempio con
cmd + . questa azione sarà effettuata su quello dei due che è di default, usualmente il localhost. Possiamo cambiare il Server di
default invocando il metodo .default
Server.default = Server.internal; Server.default = Server.local; // oppure... s = Server.local; Server.default_(s);
Server.new
Oltre ai due Server che abbiamo appena illustrato possiamo crearne quanti ne vogliamo invocando il metodo .new()
:
y = Server.new(\local2, NetAddr("127.0.0.1", 57111));
Questo metodo accetta quattro argomenti, ma i più importanti sono i primi due:
- un nome (etichetta) specificato sotto forma di simbolo che identifica il Server (come 'local' o 'internal')
- un'istanza della Classe
NetAddr.new()
che specifica:- un indirizzo IP (hostname o indirizzo MAC). Affronteremo i protocolli di rete nel Capitolo dedicato al protocollo OSC, per ora pensiamolo come a una stringa di numeri che identifica un computer (inteso come oggetto). L'indirizzo specificato nell'esempio ("127.0.0.1") è un indirizzo riservato e rappresenta il computer sul quale stiamo operando.
- una porta alla quale inviare i messaggi OSC che specifica un indirizzo preciso sul computer definito dall'indirizzo IP al quale
recapitare i messaggi. Le porte sono specificate da un numero intero. I numeri da 0 a 65.535 sono dedicati a porte riservate
e non possono essere usati, possiamo dunque scegliere qualsiasi numero superiore. Abbiamo visto come quando eseguiamo il boot appare
il messaggio
booting 57110
che riporta il numero della porta del Server di default alla quale possiamo inviare eventuali messaggi OSC.
Messaggi al Server
A qualsiasi server possiamo inviare una serie di messaggi. Di seguito i principali.
s = Server.local; s.boot; // Boot del Server y.boot; // Boot di un secondo 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.quit; // Chiude il Server s.volume = 0; // Setta il voume in uscita (in dB) s.mute; // Mute del Server s.unmute; // Unmute
Schede audio
Di default SuperCollider legge i valori in ingresso e scrive quelli in uscita sul driver utilizzato in quel momento dal sistema operativo del computer e se colleghiamo una scheda audio esterna il miglior modo di far comunicare SuperCollider con la scheda consiste nel selezionarla nelle preferenze audio di sistema. Per chi ha un computer Mac:
- Andare in menù mela e selezionare Preferenze di Sistema, si apre una finestra:
- Selezionare Suono, si apre una nuova finestra:
- Selezionare il device desiderato dalla lista sia per l'Entrata che per l'Uscita audio (possono anche essere differenti, l'importante è che abbiano la stessa rata di campionamento altrimenti i Server di SuperCollider non eseguono il boot.
Possiamo selezionare la scheda audio in uso anche dal codice invocando il metodo .options
sul Server desiderato ma lo sconsiglio
in quanto a volte può dare dei problemi:
s = Server.local; o = s.options;
Dopodichè possiamo specificare tutti i parametri che abbiamo visto descritti nella post window al momento del boot:
o.device; // riporta il device in uso o.device = "Soundflower (2ch)"; // seleziona il device specificando il nome o.device_("Soundflower (2ch)"); // altra scrittura... s.reboot; o.device = nil; // 'nil' specifica i driver del computer s.reboot;
Se vogliamo utilizzare devices differenti per i segnali inEntrata e quelli in Uscita:
o.inDevice = "Built-in Microph"; o.outDevice = "Soundflower (2ch)"; s.reboot; o.device = nil; s.reboot;
I Server di SuperCollider supportano di default 8 canali (Bus) in Uscita i cui indici vanno da 0 a 7. Se vogliamo verificare o
modificare questo parametro possiamo farlo invocando il metodo .numOutputBusChannels
. Lo stesso dicasi per i canali (Bus) in Entrata
i cui indici vanno da 8 a 15 (cambia solo il metodo):
o.numOutputBusChannels.postln; // riporta l'informazione o.numOutputBusChannels = 8; // cambia i settings o.numInputBusChannels.postln; // riporta o.numInputBusChannels = 8; // cambia
Per verificare possiamo visualizzare i meter:
( o.numOutputBusChannels = 2; // 2 canali o.numInputBusChannels = 2; // 2 canali s.meter; ) ( o.numOutputBusChannels = 8; // 8 canali o.numInputBusChannels = 8; // 8 canali s.meter; )
Possiamo specificare la Sample Rate facendo attenzione che quella scelta sia supportata dal device specificato:
o.sampleRate; // riporta o.sampleRate = 44100; // cambia
Lo stesso dicasi per il Block size che di default è di 64 samples:
o.blockSize = 64; // cambia o.blockSize; // riporta il block size corrente
Torniamo infine a quella scritta che abbiamo letto in precedenza nella Post window: a ServerOptions
. Ogni Server possiede al suo interno
un'istanza di questo oggetto che rappresenta un pacchetto di opzioni. Con questo oggetto possiamo dunque creare un pacchetto di opzioni
personalizzato da applicare a più Servers differenti. Per farlo dobbiamo:
h = ServerOptions.new; // creare una nuova istanza e assegnarla a una variabile h.sampleRate_(44100); // specificare le opzioni desiderate h.numOutputBusChannels_(2); y = Server.new(\Local2, NetAddr("127.0.0.1", 57111), h).meter; // assegnarle ad un Server come terzo argomento
Questo metodo è utile anche quando vogliamo ottenere nuovamente una lista dei devices a disposizione:
ServerOptions.devices; ServerOptions.inDevices; ServerOptions.outDevices;
Monitors
A chiosa di questo Capitolo dedicato al Server vediamo quali sono le principali possibilità che abbiamo a disposizione per monitorare le attività di un Server. Ci sono tre possibilità:
Stampare le informazioni nella Post window.
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
Al momento non sappiamo ancora nulla riguardo ad alcune informazioni appena esposte, ma ho preferito metterle in questa parte dello scritto per uniformare gli argomenti ed eventualmente ritornare in seguito a questo punto come reference.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 oppure riportarli su un'interfaccia grafica (GUI) per un monitoraggio visivo personalizzato (custom). Ad esempio vediamo come monitorare costantemente l'utilizzo medio della CPU con una
Routine
:( a = {inf.do({ ["AVG: "++s.avgCPU.round(0.001), "PEAK: "++s.peakCPU.round(0.001)].postln; 0.1.wait }) }.fork; ) a.stop;
Leggere le informazioni nell'interfaccia grafica IDE (in basso a destra).
Sono le stesse informazioni che abbiamo appena richiamato dal codice, da sinistra a destra:
- 0.00%: utilizzo medio della CPU.
- 0.00%: utilizzo di picco della CPU.
- 0u: numero di UGens attive.
- 0s: numero di Synths attivi.
- 2g: numero di Groups attivi.
- 94g: numero di SynthDef attive.
- 0.0dB: Master gain del Server.
- M: Mute (o meno).
Possiamo notare come il numero di Groups e di SynthDefs non sia 0 già dal booting de Server, senza aver fatto nulla. Questo perchè alcuni di questi dati agiscono "dietro le quinte" e sono caricati automaticamente. Se clicchiamo sui numeri appare la seguente finestra dove possiamo attivare o disattivare diversi comandi:
Creare interfacce grafiche (GUI). Possiamo infine creare alcune interfacce grafiche dedicate alla visualizzazione di alcuni parametri riguardanti i segnali audio processati nel Server come le ampiezze in input e output visualizzate attraverso PPMeters, un oscilloscopio e uno spettroscopio:
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
Possiamo infine aprire una finestra con una rappresentazione grafica del Server così come appariva fino alla versione 3.4 di SuperCollider, con la quale è possibile interagire utilizzando il mouse e dove sono riportate le stesse informazioni presenti nell'interfaccia IDE che abbiamo affrontato in precedenza.:
s.makeWindow;