Walter Cianciusi
UNO SCRIPT SCILAB COME STRUMENTO PER LA
GENERAZIONE AUTOMATICA DI COMPOSIZIONI MUSICALI ELETTROACUSTICHE
Copyright
© 2006 Walter Cianciusi
Nel corso
dell'anno 2005 chiesi al mio professore di elaborazione del segnale,
Lorenzo Seno, se fosse possibile realizzare un algoritmo in grado di
riassumere i contenuti frequenziali presenti in un segnale audio di vaste
dimensioni temporali. La domanda era volta ad accertare la concretezza di
una mia idea musicale che vedeva nella sintesi non esclusivamente il mezzo
per una generazione costruttiva del segnale ma pure uno strumento per la
riduzione del segnale a micro-entità informativa autonoma.
Lorenzo Seno fece immediatamente riferimento al calcolo della trasformata
di Fourier come metodo già più che sperimentato per ottenere una
fotografia dettagliata delle frequenze presenti in un segnale nonché
delle ampiezze relative a ciascuna delle frequenze individuate.
Effettivamente,
in presenza delle giuste condizioni, la discrete Fourier transform (DFT)
può essere utilizzata per determinare lo spettro di un segnale digitale.
La sua più comune implementazione, la fast Fourier transform (FFT), è
stata sviluppata da Cooley e Tukey e ha reso disponibile l'analisi
spettrale per la soluzione di una vasta serie di problemi nei campi più
disparati. Le analisi prodotte dagli algoritmi di DFT e FFT sono
identiche; l'unica differenza fra le due sta nella velocità
computazionale notevolmente maggiore permessa dalla FFT come risultato di
un intelligente riordino delle operazioni nella DFT.
Per conoscere
davvero lo spettro di un segnale tempo-variante, la sua forma d'onda deve
essere conosciuta per intero; un matematico direbbe che il segnale f(t)
deve essere conosciuto per tutto il tempo t da
a . Questa non è una richiesta
realistica per un segnale "reale". Di conseguenza si usa
realizzare una serie di trasformate di Fourier a breve termine (Short-term
Fourier transforms: STFTs), vale a dire una successione di FFT realizzate
su piccole porzioni della forma d'onda. L'ingresso di una singola FFT si
dice una porzione "finestrata" del segnale perché rappresenta
solo una istantanea del suono complessivo.
Quindi il segnale digitale input di una FFT è una sequenza di N campioni
finestrati del segnale da analizzare. In uscita dalla FFT avremo un set di
valori che descrivono lo spettro della forma d'onda in ingresso. Per
godere appieno dei vantaggi di velocità inerenti all'algoritmo della FFT,
N deve essere scelto come un intero potenza di due.
Presupposti
di questa tecnica sono la periodicità e la stazionarietà - la forma
d'onda all'interno della finestra ripete se stessa al di fuori della
finestra ed è prodotta da un processo che non varia.
Se la larghezza della finestra può essere adattata così che contenga un
esatto numero intero di cicli di una forma d'onda stazionaria, allora
l'uscita della DFT può essere interpretata come uno spettro armonico. Se
N è il numero di campioni della finestra, la presupposta frequenza
fondamentale del segnale che viene analizzato,
, è quella il cui periodo occupa lo spazio/tempo della finestra
d'analisi.
In effetti
l'algoritmo in questione, DFT o FFT, può essere pensato come un banco di
filtri passa-banda, uno per ciascun "canale"/frequenza
(frequenza che sia un multiplo intero della fondamentale). Se la frequenza
fondamentale della forma d'onda in analisi cade esattamente alla frequenza
di centro banda di uno dei filtri del banco, i risultati saranno accurati.
Quando il segnale in analisi è davvero periodico e contiene
esclusivamente frequenze che siano multipli interi di ,
si parla di analisi pitch-synchronous. Questa situazione consente alla FFT
di estrarre le ampiezze precise delle varie parziali armoniche.
Di fatto è una situazione più che rara e dunque è bene considerare le
conseguenze di un difetto di queste condizioni ideali. Il caso cioè in
cui i filtri immaginari di cui abbiamo parlato non si trovino ad essere
centrati sulle armoniche della fondamentale (quest'ultima, lo ricordiamo,
data dalla lunghezza della finestra): avremmo una ricostruzione dello
spettro meno fedele al segnale originale. Anche se il segnale fosse una
semplice sinusoide (ma il suo periodo non fosse perfettamente inquadrato
nella finestra d'analisi) si genererebbe una ricostruzione dello spettro
in cui tutti i diversi filtri/"canali" verrebbero coinvolti.
Per rimediare ad un problema del genere è opportuno scegliere un numero
di punti molto elevato per la finestra d'analisi, cosicché differenze
frequenziali minime rientrino nell'ambito del pettine di armoniche della
fondamentale.
Ha suscitato
grande interesse in me l'ulteriore possibilità, suggerita dal professor
Seno, di ricostituire la originale forma d'onda sottoposta ad analisi
attraverso una DFT o FFT inversa. Non va dimenticato infatti che la
trasformata di Fourier consente di conservare i dati relativi alla fase
delle singole parziali.
Cosa accade, però, se la trasformata inversa non tiene conto dei valori
relativi alla fase delle parziali? Tutte le parziali tenteranno di
ricostruire il segnale originale partendo da fase 0°. Ciò genererà una
notevole elaborazione dell'originale segnale, ma verrà comunque
preservato un certo "sapore" spettrale (si badi: ci riferiamo
ora a spettri d'ampiezza, non di fase). Ecco dunque l'idea compositiva:
prendere una registrazione digitale di una composizione musicale x,
realizzare su tale segnale una serie di FFT scegliendo una finestra
d'analisi notevolmente lunga (
punti) così da rendere molto fitto il pettine di armoniche della
fondamentale, calcolare poi la media delle FFT ponendo a zero la fase e
antitrasformare il risultato.
Si ottiene così una frame di lunghezza pari a quella della finestra
d'analisi che riassume il contenuto frequenziale di tutto il brano. Si
noti che l'ampiezza di ciascuna parziale viene determinata come media
dell'ampiezza rintracciata per quella frequenza in ciascuna frame.
Inoltre, essendo stata posta la fase a zero, la frame inizia e termina con
uno zero.
Tale frammento/timbro può essere ripetuto più volte in loop senza avere
click ai bordi proprio grazie alla continuità di fase.
Sulla scorta
di questa idea compositiva Lorenzo Seno ha realizzato uno script Scilab
che effettua le operazioni d'analisi, di media e l'antitrasformata.
Analizziamo il codice nel dettaglio:
stacksize(12000000);
// con questo comando si riservano al processo alcune locazioni di memoria
clear;
// pulisce la memoria da eventuali precedenti run
filename=tk_getfile();
// nome del file
NF = 20; //
esponente della lunghezza della frame (nell'esempio: 20)
frlen = 2^NF;
// lunghezza della frame (ricordiamo che per realizzare una FFT è
necessario che la lunghezza della frame corrisponda ad un numero di punti
potenza di due)
// snd contiene i dati audio, SF
la freq. di campionamento, BITS i bit del campione
[lun SF BITS]=wavread(filename,'size');
// La funzione tira fuori tre argomenti dalla lettura del file .wav
che vogliamo sottoporre ad analisi: il primo è un vettore che dà
lunghezza e canali, il secondo è la frequenza di campionamento, il terzo
i bit di quantizzazione
chan = lun(2);
lun = lun(1);
tipo='mono';
if (chan > 1) then
tipo='stereo' ;
end;
printf("\nFile:
%s\nFreq. campionamento: %d Hz\nbit/campione: %d - %s\n", filename,SF,BITS,tipo);
printf("Lunghezza frame: %d campioni\n",frlen);
nframes =ceil(lun/frlen);
printf("Lunghezza del file in campioni: %d - frames: %d\n",lun,nframes);
// si determina la visualizzazione a schermo delle seguenti informazioni:
frequenza di campionamento, bit di quantizzazione, numero di canali (mono/stereo),
lunghezza della frame, lunghezza del file in campioni, numero totale di
frame
frames =
nframes - 1; // numero di frame sicuramente intere
lastfr_len
= lun - frames * frlen; // lunghezza dell'ultima frame
sframe(1:frlen,
1:chan)=0; // frame iniziale con tutti zeri
// Ora leggiamo il file a pezzi,
facciamo spettri d'ampiezza e sommiamo le antitrasformate con fase 0°
for (i=1:frames)
sstart = (i-1)*frlen+1;
send = sstart + frlen - 1;
snd = wavread(filename,[sstart send]);
for (i=1:chan)
Ssnd(:,i)= fft(snd(:,i),-1);
end;
sframe = sframe + Ssnd;
printf("."); // per ogni
ciclo viene visualizzato sullo schermo un puntino
end;
// Il rapporto fra il numero
complessivo di campioni del file .wav e la lunghezza della frame può non
essere un intero. In tal caso l'ultima frame è tronca.
Si procede allora con la tecnica dello zero padding, cioè aggiungendo
campioni con valore zero al termine dell'ultima frame, così da ottenere
per essa il medesimo numero di campioni presenti nelle altre frame.
sstart = frames*frlen +1;
send = sstart + lastfr_len - 1;
snd = wavread(filename,[sstart send]);
snd(frlen,1)=0;
for (i=1:chan)
Ssnd(:,i)= fft(snd(:,i),-1);
end;
sframe = sframe + Ssnd;
// Fatto. Ora si genera il file di uscita antitrasformando Sframe,
che è solo immaginario, parte reale nulla, e quindi ha fase 0
for (i=1:chan)
sframe(:,i) = abs(sframe(:,i))*%i.*sign(imag(sframe(:,i))); // mette a
zero la fase
frame(:,i) = fft(sframe(:,i),1); // antitrasforma e ripassa nel dominio
del tempo
end;
// Genera il nome del file
aggiungendo una specifica relativa alla lunghezza della frame
vchar = [1:length(filename)-4];
filen = part(filename, vchar);
fileout = filen + '_S2_'+string(frlen)+'.wav';
// Ora fa il valore medio; frame
= frame / nframes; cerca il massimo tra i canali
Max = 0;
for (i=1:chan)
Maxx = max(abs(frame(:,i)));
Max = max(Maxx, Max);
end;
// Normalizza a 0.9
frame = 0.9*(frame / Max);
//Visualizza a schermo
"Genero il file... .wav"
printf("\nGenero il file %s ...", fileout);
// Controlla se il file esiste
[x, err] = fileinfo(fileout);
if (err == 0) then
// Il file esiste, cancellarlo
TCL_EvalStr('file delete '+fileout);
end;
wavwrite(frame,SF,BITS,fileout);
// Visualizza a schermo
"fatto!"
printf("fatto!\n");
Abbiamo così
creato, nella stessa directory in cui si trovava il file da analizzare, un
frammento che riassume i contenuti frequenziali del brano. Non essendo
state mantenute le relazioni di fase, l'unico rimando all'originale è di
natura timbrica.
Con questa
tecnica sono state realizzate alcune delle mie più recenti opere
elettroacustiche. In particolare la prima ad esser stata pubblicata si
intitola #70 (da Richard Strauss "Serenata in mi bemolle maggiore per
13 strumenti a fiato op. 7"). Dopo aver assimilato concettualmente il
timbro musicale al colore della visione, ho tentato di riprodurre in
questo brano la medesima struttura spaziale (leggi ritmica) di alcune
opere dell'artista visivo Daniel Buren.

Proprio come nell'immagine
qui sopra riportata, nella mia opera il frammento di colore/timbro
ottenuto dall'analisi viene alternato ad un vuoto suggerito dal silenzio
digitale. Poi di nuovo si riascolta il frammento, poi di nuovo il
silenzio. Questo per 10 volte in #70.
Nonostante la perfetta eguaglianza fra il numero di campioni che esprimono
il frammento di suono e il numero di campioni che esprimono la sezione di
silenzio, una esposizione prolungata a siffatta struttura "ad
intermittenza" suggerisce percettivamente una maggiore durata della
sezione suono rispetto a quella silenzio. Ecco perché ritengo
assolutamente necessario nello sviluppo delle mie prossime opere di simile
struttura tener conto di alcune nozioni che la psicoacustica va mutuando
dalla Gestalt. In particolare esperimenti realizzati utilizzando un
segnale interrotto da brevi e periodici silenzi hanno svelato la capacità
di ricostruire a livello neuronale parte del segnale celato dal silenzio.
Questa capacità è tanto più esaustiva quanto più risulti evidente un
principio di causa/effetto fra ciò che precede e ciò che segue il
silenzio: si immagini una struttura tonale romantica.
V'è di più: è possibile, ferma restando una struttura simmetrica
suono-silenzio, suggerire attraverso spunti della visione la struttura
riportata nella precedente immagine? In altre parole è possibile che
interventi mirati di light design restituiscano la percezione delle giuste
proporzioni fra suono e silenzio? E' proprio per rispondere a questi
interrogativi che ancora una volta ritengo debba farsi riferimento alla
teoria della Gestalt.
Un'ulteriore deriva dei
risultati dell'algoritmo si ha in altre mie opere, pure recenti, in cui il
frammento ottenuto dall'analisi viene ripetuto più volte in loop. Grazie
alla continuità di fase (ricordiamo che la frame ottenuta inizia e
termina con uno zero) non è possibile percepire la transizione da una
lettura del frammento alla successiva. Dunque si genera una sorta di
bordone che rende possibile indagare nel dettaglio il timbro ottenuto.
Qualcosa di simile a ciò che accade nelle opere di La Monte Young, ma in
relazione ad un segnale estremamente più complesso: le ultime
istallazioni sonore di La Monte Young prevedono l'utilizzo di 35
oscillatori sinusoidali; nel nostro caso, se pensiamo a ciascun
"canale" della FFT come ad un autonomo oscillatore sinusoidale,
e consideriamo una finestra d'analisi lunga
punti, il segnale viene ricostruito come somma di 524288 parziali
sinusoidali.
Un paragone può essere effettuato pure con le pitture monocrome di Yves
Klein.

Proprio come
Klein aveva fatto brevetto del suo particolarissimo blu, così mi piace
pensare all’algoritmo in questione come ad una sorta di oracolo del
timbro che, data una delle due strutture formali sopra descritte, possa
essere consultato per la generazione automatica di composizioni musicali
elettroacustiche. |