Segnali e Buffers

In diverse tecniche di elaborazione del segnale in tempo reale è necessario registrare frammenti di suono più o meno lunghi in uno o più Buffer.

Per alcune di queste come quelle legate all'analisi e ri-sintesi FFT basta un Buffer di pochi campioni (512, 1024, 2048) mentre per altre come la sintesi granulare dovremo utilizzare Buffers nell'ordine di millisecondi o secondi.

Allocazione della memoria

La prima cosa che dobbiamo fare è riservare uno spazio di memoria vuoto su di un Server che riempiremo dinamicamente in seguito con i valori di un segnale. Possiamo farlo invocando il metodo .alloc() su un'istanza di Buffer:

(
s.boot;
s.scope;
s.meter;
s.plotTree;
)

(
Buffer.freeAll;                      // Prima pulisce tutto...
f = Buffer.alloc(s,                  // server
                 s.sampleRate * 0.5, // lunghezza in frames
                 1);                 // numero di canali
				 
g = Buffer.alloc(s, s.sampleRate * 0.5, 2);
)

f.plot;
g.plot;

Scrittura segnali

Possiamo scrivere i valori di uno o più segnali audio in un Buffer con la UGen RecordBuf.ar() che attraverso settaggi combinati dei suoi argomenti ci permette di sfruttare diverse possibilità.

Come prima cosa però creiamo due Synths differenti che scrivono il loro output su due Buses diversi (in questo caso 9 e 10).

Il primo sintetizza un segnale audio direttamente in SuperCollider mentre il secondo legge un segnale dagli input audio del computer o della soundcard con la UGen SoundIn.ar() che accetta come primo argomento il Bus (o un Array di Buses nel caso di più canali in ingresso) dal quale leggere i valori.

(
SynthDef(\noise,   {arg busOut=9, gain=0;
	                Out.ar(busOut, PinkNoise.ar*gain.lag(0.2))
}).add;

SynthDef(\microf,  {arg busIn=0,busOut=10,gain=0;
	                Out.ar(busOut, SoundIn.ar(busIn)*gain.lag(0.2))
}).add;
)	

Possiamo anche fermare la registrazione con l'argomento run:0 oppure specificare un offset in samples per non cominciare a scrivere nel Buffer dall'inizio con l'argomento offset:n.

Array di Buffers

Se vogliamo utilizzare più di un Buffer anche in questo caso conviene collezionarli in un Array per poi richiamarli con gli indici come abbiamo fatto per caricare cartelle di soundfiles

~durs  = [2,5,0.1,0.02322]*s.sampleRate;
~bufs  = ~durs.collect{arg i; Buffer.alloc(s, i.round, 1)};

Synth.tail(s,\recBmono1, [\buf,~bufs[0].bufnum,\bus,10,\gain,1]);
Synth.tail(s,\recBmono1, [\buf,~bufs[1].bufnum,\bus,10,\gain,1]);
Synth.tail(s,\recBmono1, [\buf,~bufs[2].bufnum,\bus,10,\gain,1]);
Synth.tail(s,\recBmono1, [\buf,~bufs[3].bufnum,\bus,10,\gain,1]);

(
~bufs[0].plot; 
~bufs[1].plot; 
~bufs[2].plot; 
~bufs[3].plot;
)