Mid-Side. Appunti.
da alcuni appunti sulla Stereofonia
Sto scrivendo un testo/lezione dal titolo Esposizioni Elettroacustiche (per il quale Simone Pappalardo ha suggerito il sottotitolo Tecniche Estese di Amplificazione, Stereofonia, Spazializzazione e Proiezione Sonora).
Preparando una parte dedicata al trattamento Mid-Side mi sono dedicato ad appuntare una serie di passi che portano ad una coppia di file MS partendo da un file LR attraverso la console di Octave.
Il brano che sto usando per preparare la lezione è Canto di Madre di Michelangelo Lupone,
quindi per seguire e provare lo script con altri file è necessario sostituire Cantodimadre.wav
con il nome del file che si intende utilizzare.
Aperto Octave, il primo passo è caricare il file audio, lo si può fare attraverso
la funzione audioread()
ma dato che utilizzeremo il nome del file un paio di volte
conviene semplificarsi la vita dichiarando il nome del file:
filename = 'Cantodimadre.wav';
In questo modo si può chiedere a Octave di scrivere le informazioni del file che si intende processare (e per utilizzi successivi sostituire il nome del file solo nella prima funzione).
info = audioinfo(filename)
La funzione audioinfo()
restituisce le seguenti informazioni:
octave:2> info = audioinfo(filename)
info =
scalar structure containing the fields:
Filename = /Users/giuseppe/gscloud/gitrepo/ee-teassps/codes/faust/Cantodimadre.wav
CompressionMethod =
NumChannels = 2
SampleRate = 44100
TotalSamples = 18098640
Duration = 410.40
BitsPerSample = 16
BitRate = -1
Title =
Artist =
Comment =
Dalle quali si nota che il file contiene i due canali che servono per ottenere le componenti Mid-Side e l’informazione sulla frequenza di campionamento, necessaria per non commettere errori.
A questo punto si dichiara a che frequenza di campionamento si processa il file (la stessa del file originale):
fs = 44100;
Si procede alla creazione di una matrice di valori, uno per ogni campione, per ogni canale del file che si sta leggendo.
[LR, fs] = audioread(filename);
È importante notare che in ambiente Octave il carattere ;
produce il risultato
dell’operazione ma non lo stampa nella console. Il comando precedente privato del
carattere ;
produrrebbe una lista di valori in una matrice avente tante colonne
quanti i canali del file audio, per ogni campione, per tutta la durata del file.
A seconda della macchina che avete sotto le dita, ci potrebbe volere più tempo a stampare i valori che ad ascoltarlo. Provare per credere :)
0.00000 0.00000
-0.00009 -0.00009
-0.00018 -0.00015
-0.00031 -0.00024
-0.00040 -0.00031
-0.00049 -0.00040
-0.00058 -0.00049
-0.00067 -0.00055
-0.00079 -0.00064
-0.00089 -0.00073
-0.00095 -0.00079
-0.00104 -0.00082
-0.00104 -0.00085
-0.00113 -0.00089
-0.00110 -0.00092
-0.00116 -0.00098
-0.00122 -0.00101
-0.00122 -0.00104
-0.00128 -0.00107
-0.00131 -0.00110
-0.00137 -0.00116
-0.00134 -0.00116
-0.00134 -0.00113
-0.00134 -0.00113
-0.00134 -0.00110
-0.00134 -0.00113
-0.00134 -0.00116
-0.00134 -0.00113
-0.00134 -0.00110
-0.00134 -0.00116
-0.00137 -0.00113
-0.00134 -0.00113
-0.00137 -0.00113
-0.00137 -0.00110
-0.00137 -0.00113
-0.00137 -0.00113
-0.00137 -0.00110
-0.00137 -0.00113
-0.00137 -0.00113
-0.00134 -0.00113
-0.00137 -0.00113
-0.00137 -0.00116
-0.00134 -0.00116
-0.00137 -0.00116
Questa una sequenza di 44 campioni (circa un millesimo di secondo) estrapolata nel momento in cui il file inizia a contenere suono.
Una matrice di conversione LR2MS è composta da due equazioni:
M = 0.5(L+R)
S = 0.5(L-R)
ovvero la somma e la differenza tra i due canali che compongono una coppia LR con ampiezza dimezzata. In Octave produrremo quindi la somma (dimezzata) tra le due colonne, campione per campione:
mid = 0.5*sum(LR,2);
e la differenza (dimezzata) delle due colonne campione per campione:
side = 0.5*(LR(:,1)-LR(:,2));
A questo punto non ci resta che chiedere a Octave di svuotare rispettivamente
mid
(che sarà una lista di valori somma delle due colonne, una per ogni campione) e
side
(che sarà una lista di valori differenza delle due colonne, una per ogni campione)
dentro due nuovi file, dando prima il nome
midfile = 'Cantodimadre.mid.wav';
e side:
sidefile = 'Cantodimadre.side.wav';
e poi scrivendoli sul disco:
audiowrite(midfile, mid, fs);
e side:
audiowrite(sidefile, side, fs);
La magia è fatta. Di seguito tutti i passi in un unico blocco di codice:
octave:1> filename = 'Cantodimadre.wav';
octave:2> info = audioinfo(filename)
info =
scalar structure containing the fields:
Filename = /Users/giuseppe/gscloud/gitrepo/ee-teassps/codes/faust/Cantodimadre.wav
CompressionMethod =
NumChannels = 2
SampleRate = 44100
TotalSamples = 18098640
Duration = 410.40
BitsPerSample = 16
BitRate = -1
Title =
Artist =
Comment =
octave:3> fs = 44100;
octave:4> [LR, fs] = audioread(filename);
octave:5> mid = 0.5*sum(LR,2);
octave:6> side = 0.5*(LR(:,1)-LR(:,2));
octave:7> midfile = 'Cantodimadre.mid.wav';
octave:8> sidefile = 'Cantodimadre.side.wav';
octave:9> audiowrite(midfile, mid, fs);
octave:10> audiowrite(sidefile, side, fs);
octave:11> quit