Sintesi Vettoriale¶
Spettri variabili¶
Tecnica derivata dalla sintesi per funzione d'onda (wts).
Permette di generare spettri variabili nel tempo attraverso una lettura interpolata di due o più wavetables adiacenti realizzata attraverso un segnale puntatore.
Array di Buffers¶

- Definiamo un Array di Buffers consecutivi.
- Disegnamo una forma d'onda diversa per ognuno (se vogliamo suoni omogenei le diverse forme d'onda non devono essere troppo differenti).
Possiamo richiamare ed effettuare qualisasi operazione su di ogni singolo Buffer attraverso il metodo .at().
s.boot;
s.scope;
s.freqscope;
s.plotTree
(
Buffer.freeAll;
b = Buffer.allocConsecutive(4, // Numero di Buffer
s, // Server
1024); // Size di ogni singolo Buffer (multiplo di 2)
)
(
b[0].sine1([1,0.3,0.5,0.7],true,true); // asWavetable !!!
b[1].sine1([0.2,0.4,1.3,0.6],true,true);
b[2].sine1([1,0.2,0.5,0.6,1.3,0.5],true,true);
b[3].sine1([1.3,0.3,0.5,0.7,0.8,0.9,0.2,0.3],true,true);
)
b.at(0);
b[0].plot;
b.do(_.free); // libera l'Array di Buffer
VOsc.ar¶
Oscillatore tabellare dedicato alla sintesi vettoriale.
Simile a Osc.ar(), accetta come primo argomento un segnale puntatore che indica il punto di interpolazione tra i Buffers compreso tra 0 e il size dell'Array di Buffers.
(
SynthDef(\vec_1, {arg buf=0,bufn=4,freq=400,amp=0,pan=0,gate=0,done=2;
var pos,sig,env;
pos = MouseX.kr(buf, bufn.asFloat).poll(10);
sig = VOsc.ar(pos, freq);
env = Linen.kr(gate,doneAction:done);
sig = Pan2.ar(sig*amp*env,pan);
Out.ar(0, sig)
}).add;
)
(
a = Synth(\vec_1, [\buf ,b[0],
\bufn, b.size-1,
\freq,400,
\amp,1,
\pan,0,
\gate,1]);
)
a.set(\gate,0);
Mapping dei parametri¶
Ci sono diverse tecniche per generare e mappare valori da impiegare come segnale di controllo (puntatore).
Per ottenere una maggiore compatibilità tra le diverse tecniche normalizziamo il range del segnale puntatore tra +/- 1.0.
Argomenti¶
Specificandoli come argomenti (valori discreti).
Dobbiamo convertire i valori discreti in un segnale di controllo con il metopdo .lag().
(
SynthDef(\vec_2, {arg buf=0, bufn=4, pos= -1, lag=0.02, freq=400, amp=0, pan=0, gate=0, done=2;
var sig, env;
sig = VOsc.ar(pos.linlin(-1,1,buf,bufn).lag(lag), freq);
env = Linen.kr(gate, doneAction:done);
sig = Pan2.ar(sig*amp*env,pan);
Out.ar(0, sig)
}).add;
)
a = Synth(\vec_2, [\buf,b[0], \bufn,b.size-1, \freq,400, \amp,1, \pan,0, \gate,1]);
a.set(\lag, 5, \pos,rand2(1.0).postln);
a.set(\gate,0);
Segnale di controllo esterno¶
- Definiamo un Bus di controllo.
- Definiamo una SynthDef che generi un segnale di controllo (in questo esempio la posizione del mouse riscalata tra +/-1.0.
- Definiamo un Synth che genera il segnale di controllo e lo scrive sul Bus di controllo.
- Passiamo i valori scritti sul Bus dio controllo al Synth dedicato alla sintesi vettoriale come abbiamo fatto con gli argomenti invocando il metodo .asMap.
(
~mouseY = Bus.control(s, 1); // Bus di controllo (server, n_canali)
SynthDef.new(\mouse, {arg busOut=0;
var sig;
sig = MouseY.kr(-1,1).poll(10);
Out.kr(busOut,sig)
}).add;
)
(
m = Synth(\mouse, [\busOut, ~mouseY]) ; // Synth per ksig
a = Synth(\vec_2, [\buf, b[0], // Synth per vettoriale
\bufn, b.size-1,
\freq, 400,
\amp, 1,
\pan, 0,
\gate,1],
s, \addToTail); // Deve essere dopo il Synth del Mouse
)
a.set(\lag, 0.02, \pos, ~mouseY.asMap); // Mappa il parametro sul control bus...
a.set(\lag, 5, \pos, rand2(1.0).postln); // Scollega il bus e torna discreto
a.set(\gate,0); m.free; ~mouseY.free;
Inviluppo d'ampiezza¶
Possiamo riscalare i valori dell'inviluppo d'ampiezza di un segnale per impiegarli come segnale di controllo che ne modifica dinamicamente il timbro.
(
SynthDef(\vec_3, {arg buf=0,bufn=4,freq=400,dur=1,amp=0,pan=0,t_gate=0,done=2;
var sig,env;
env = Env.sine(dur);
env = EnvGen.ar(env,t_gate,doneAction:done);
sig = VOsc.ar(env.linlin(0,1,buf,bufn-1.001), freq);
sig = Pan2.ar(sig*amp*env,pan);
Out.ar(0, sig)
}).add;
)
(
Synth(\vec_3, [\buf, b,
\bufn,4,
\freq,rrand(70, 96).midicps,
\dur, rrand(1,8),
\amp, rand(1.0),
\pan, rand2(1.0),
\t_gate,1]);
)
Segnale di controllo interno¶
Avendo normalizzato i valori del segnale puntatore in un range compreso tra +/- 1.0 possiamo impiegare qualsiasi segnale bipolare generato da una qualsiasi UGen per modificare il timbro di una sintesi vettoriale.
(
SynthDef(\vec_4, {arg buf=0,bufn=4,freq=400,kfreq=0.5,dur=1,amp=0,gate=0,done=2;
var sig,ksig,env;
env = Linen.kr(gate,doneAction:done);
ksig = LFNoise1.kr(kfreq); // ksig (+/- 1)
sig = VOsc.ar(ksig.range(buf,bufn-1), freq); // Ksig riscalato
sig = Pan2.ar(sig * amp * env, ksig); // controlla anche il pan
Out.ar(0, sig)
}).add;
)
(
a = Synth(\vec_4, [\buf, b,
\bufn,4,
\freq,rrand(70, 96).midicps,
\dur, rrand(0.1,2),
\amp, rand(1.0),
\gate,1]);
)
a.set(\kfreq, 2); // Frequenza del segnale di controllo
a.set(\kfreq, 0.7);
a.set(\gate, 0);
Chorusing¶
Il chorusing è una tecnica per simulare la molteplicità di voci di un coro dove più cantanti eseguono la stessa linea melodica.
Sia la frequneza che i transitori d'attacco di ogni singola voce sono imprecisi ovvero ci sono differenze di poche Hz e pochi millisecondi.
Se volessimo applicare questa tecnica alla sintesi vettoriale in SuperCollider abbiamo a disposizione la UGen VOsc3.ar() che rpermette di specificare tre frequenze diverse per ogni Synth (ma non diversi tempi d'attacco).
(
SynthDef(\vec_3, {arg buf=0,bufn=4,freq=#[440,445,435],amp=0,pan=0,gate=0,done=2;
var pos,sig,env;
pos = LFNoise1.kr(0.2);
sig = VOsc3.ar(pos.range(0.0,bufn-1.001),
freq[0],freq[1],freq[2]);
env = Linen.kr(gate,doneAction:done);
sig = Pan2.ar(sig*amp.lag(2)*env);
Out.ar(0, sig)
}).add;
)
(
a = Synth(\vec_3, [\buf, b[0],
\bufn, b.size-1,
\freq, 3.collect({rrand(200,1000)}).postln,
\amp,0.3,
\pan,0,
\gate,1]);
)
a.set(\freq,[438,440,442]);
a.set(\gate,0);
Notiamo infine come tutte le strategie appena illustrate siano nella direzione del rendere più espressivi e naturali i suoni generati dalla sintesi per funzione d'onda.