Forme d'onda libere

Questo tipo di oscillatori ci permette di leggere qualsiasi forma d'onda memorizzata in un Buffer attraverso le tecniche illustrate nel paragrafo dedicato. Generano suoni a spettro fisso e per questo motivo possiamo controllare dinamicamente solo: frequenza, ampiezza (inviluppo) e panning. Storicamente questi parametri venivano controllati attraverso tastiere MIDI ma qualsiasi tipologia di controllo è possibile.

BufRd.ar()

BufRd.ar() è una UGen molto versatile in quanto possiamo utilizzarla sia per il playback e l'elaborazione di Buffers lunghi sia come oscillatore tabellare. In entrambi i casi i valori memorizzati nel Buffer devono essere sotto forma di Float Array e non in Wavetable format (asWavetable). E' possibile scegliere il tipo di interpolazione specificandolo come argomento. In questo caso l'interpolazione avviene in fase di lettura senza modificare il Buffer.

s.boot;
s.plotTree;

Buffer.freeAll;
b = Buffer.alloc(s,1024);            // Buffer con size multiplo di 2
b.sine1([1,0.3,0.5,0.7],true,false); // Ampiezze, normalizza, asWavetable

(
// --------------------- Con fase di sostegno

SynthDef(\osc_1, {arg buf=0,freq=400,amp=0,pan=0,gate=0,done=2;
                  var punta,sig,env,pann;
                      punta = LFSaw.ar(freq).range(0,BufFrames.kr(buf));
                      sig   = BufRd.ar(1, buf, punta,interpolation:4);
                      env   = Linen.kr(gate,doneAction:done);
                      pann  = Pan2.ar(sig*amp.lag(2)*env);
                  Out.ar(0, pann)
        }).add;

// --------------------- Senza fase di sostegno

SynthDef(\osc_2, {arg buf=0,freq=400,dur=1,amp=0,pan=0,t_gate=0,done=2;
                  var punta,sig,bpf,env,pann;
                      punta = LFSaw.ar(freq).range(0,BufFrames.kr(buf));
                      sig   = BufRd.ar(1, buf, punta,interpolation:4);
                      bpf   = Env.perc(0.01,dur-0.01);
                      env   = EnvGen.kr(bpf,doneAction:done);
                      pann  = Pan2.ar(sig*amp.lag(2)*env);
                  Out.ar(0, pann)
        }).add;
)

a = Synth(\osc_1, [\buf,b,\freq,400,\amp,1,\pan,0,\gate,1]);
a.set(\freq,rrand(200, 1000),\amp,rand(1.0),\pan,rand2(1.0))
a.set(\gate,0);

(
Synth(\osc_2, [\buf,b,
               \freq,rrand(60, 72).midicps,
               \dur,rrand(0.1,2),
               \amp,rand(1.0),
               \pan,rand2(1.0),
               \t_gate,1]);
)

OscN.ar()

OscN.ar() è un oscillatore tabellare che non realizza nessun tipo di interpolazione. Anche in questo caso i valori memorizzati nel Buffer devono essere sotto forma di Float Array e non in Wavetable format (asWavetable).

Buffer.freeAll;
b = Buffer.alloc(s,1024);            // Buffer con size multiplo di 2
b.sine1([1,0.3,0.5,0.7],true,false); // Ampiezze, normalizza, asWavetable

(
// --------------------- Con fase di sostegno

SynthDef(\osc_3, {arg buf=0,freq=400,amp=0,pan=0,gate=0,done=2;
                  var sig,env,pann;
                      sig   = OscN.ar(buf, freq);
                      env   = Linen.kr(gate,doneAction:done);
                      pann  = Pan2.ar(sig*amp.lag(2)*env);
                  Out.ar(0, pann)
        }).add;

// --------------------- Senza fase di sostegno

SynthDef(\osc_4, {arg buf=0,freq=400,dur=1,amp=0,pan=0,t_gate=0,done=2;
                  var sig,bpf,env,pann;
                      sig   = OscN.ar(buf, freq);
                      bpf   = Env.perc(0.01,dur-0.01);
                      env   = EnvGen.kr(bpf,doneAction:done);
                      pann  = Pan2.ar(sig*amp.lag(2)*env);
                  Out.ar(0, pann)
        }).add;
)

a = Synth(\osc_3, [\buf,b,\freq,400,\amp,1,\pan,0,\gate,1]);
a.set(\freq,rrand(200, 1000),\dur,rrand(0.1,2),\amp,rand(1.0),\pan,rand2(1.0))
a.set(\gate,0);

(
Synth(\osc_4, [\buf,b,
               \freq,rrand(60, 72).midicps,
               \dur,rrand(0.1,2),
               \amp,rand(1.0),
               \pan,rand2(1.0),
               \t_gate,1]);
)

Osc.ar()

Osc.ar() è un oscillatore tabellare che realizza un'interpolazione lineare. Per questo motivo i valori memorizzati nel Buffer a differenza degli altri devono essere sotto forma di Wavetable format (asWavetable) e non in Float Array. In questo formato i valori interpolati sono scritti direttamente nel Buffer e non generati in fase di lettura.

Buffer.freeAll;
b = Buffer.alloc(s,1024);            // Buffer con size multiplo di 2
b.sine1([1,0.3,0.5,0.7],true,true);  // asWavetable !!!

(
// --------------------- Con fase di sostegno

SynthDef(\osc_5, {arg buf=0,freq=400,amp=0,pan=0,gate=0,done=2;
                  var sig,env,pann;
                      sig   = Osc.ar(buf, freq);
                      env   = Linen.kr(gate,doneAction:done);
                      pann  = Pan2.ar(sig*amp.lag(2)*env);
                  Out.ar(0, pann)
        }).add;

// --------------------- Senza fase di sostegno

SynthDef(\osc_6, {arg buf=0,freq=400,dur=1,amp=0,pan=0,t_gate=0,done=2;
                  var sig,bpf,env,pann;
                      sig   = Osc.ar(buf, freq);
                      bpf   = Env.perc(0.01,dur-0.01);
                      env   = EnvGen.kr(bpf,doneAction:done);
                      pann  = Pan2.ar(sig*amp.lag(2)*env);
                  Out.ar(0, pann)
        }).add;
)

a = Synth(\osc_5, [\buf,b,\freq,400,\amp,1,\pan,0,\gate,1]);
a.set(\freq,rrand(200, 1000),\dur,rrand(0.1,2),\amp,rand(1.0),\pan,rand2(1.0))
a.set(\gate,0);

(
Synth(\osc_6, [\buf,b,
               \freq,rrand(60, 72).midicps,
               \dur,rrand(0.1,2),
               \amp,rand(1.0),
               \pan,rand2(1.0),
               \t_gate,1]);
)

Forme d'onda periodiche

In SuperCollider (come nella maggior parte dei software audio) ci sono oscillatori tabellari dedicati alla generazione di forme d'onda classiche a spettro fisso e spettro variabile. In questo paragrafo illustriamo quelli realizzati attraverso funzioni d'onda deterministiche tutte a banda di frequenza limitata (bandlimited) per ovviare a effetti di aliasing. Nel paragrafo dedicato ai segnali di controllo possiamo trovare le versioni non limitate (LF UGens).

Negli esempi seguenti è utilizzata una sintassi semplificata per focalizzare l'attenzione sul timbro. Le UGens possono essere integrate nelle SynthDef illustrate in precedenza.

Sinusoide (Sine)

Il suono più puro sintetizzabile.

image not found

s.boot;
s.plotTree;
s.scope;
s.freqscope;

(
SynthDef(\sine, {arg freq=400,amp=0,gate=0;
	             var sig,fade,out;
                     sig  = SinOsc.ar;
                     fade = Linen.kr(gate,doneAction:2);
                     out  = sig*fade*amp.lag(0.2);
                 Out.ar(0, out)
         }).add;
)

a = Synth(\sine, [\freq,400,\amp,1,\gate,1]);
a.set(\gate,0);

Treno d'impulsi (ImPulse train)

Lo spettro è caratterizzato dalla presenza di tutti gli armonici con la stessa ampiezza e fase.

image not found

(
SynthDef(\imPu, {arg freq=400,nHarm=10,amp=0,gate=0;
	             var sig,fade,out;
                     sig  = Blip.ar(freq,nHarm);
                     fade = Linen.kr(gate,doneAction:2);
                     out  = sig*fade*amp.lag(0.2);
                 Out.ar(0, out)
         }).add;
)

a = Synth(\imPu, [\freq,400,\amp,1,\gate,1]);
a.set(\nHarm,rrand(1,30).postln);
a.set(\gate,0);

Dente di sega (Sawtooth)

Lo spettro è caratterizzato dalla presenza di tutti gli armonici con l'ampiezza che decade secondo la formula 1/numero_di_armonico e fuori fase di 180°.

image not found

(
SynthDef(\sega, {arg freq=400,amp=0,gate=0;
	             var sig,fade,out;
                     sig  = Saw.ar(freq);
                     fade = Linen.kr(gate,doneAction:2);
                     out  = sig*fade*amp.lag(0.2);
                 Out.ar(0, out)
         }).add;
)

a = Synth(\sega, [\freq,400,\amp,1,\gate,1]);
a.set(\gate,0);

Triangolare (Triangle)

Lo spettro è caratterizzato dalla presenza dei soli armonici dispari con l'ampiezza che decade secondo la formula (1/numero_di_armonico)^2 e fuori fase di 180°.

image not found

(
SynthDef(\tria, {arg freq=400,amp=0,gate=0;
	             var sig,fade,out;
                     sig  = VarSaw.ar(freq,0,0.5);
                     fade = Linen.kr(gate,doneAction:2);
                     out  = sig*fade*amp.lag(0.2);
                 Out.ar(0, out)
         }).add;
)

a = Synth(\tria, [\freq,400,\amp,1,\gate,1]);
a.set(\gate,0);

Duty Cycle Saw (PWM Saw)

Lo spettro dipende dalla percentuale di Duty cycle sia per quanto riguarda la presenza degli armonici che per quanto riguarda la loro ampiezza. E' generata da VarSaw.ar() il cui terzo argomento definisce il duty cycle sotto forma di fattore di moltiplicazione (50% = 0.5).

(
SynthDef(\stri, {arg freq=400,duty=0.1,amp=0,gate=0;
	             var sig,fade,out;
                     sig  = VarSaw.ar(freq,0,duty);
                     fade = Linen.kr(gate,doneAction:2);
                     out  = sig*fade*amp.lag(0.2);
                 Out.ar(0, out)
         }).add;
)

a = Synth(\stri, [\freq,400,\amp,1,\gate,1]);
a.set(\gate,0);

Quadra (Pulse train)

Lo spettro è caratterizzato dalla presenza dei soli armonici dispari con l'ampiezza che decade secondo la formula 1/numero_di_armonico e tutti in fase.

image not found

(
SynthDef(\quad, {arg freq=400,amp=0,gate=0;
	             var sig,fade,out;
                     sig  = Pulse.ar(freq,0.5);
                     fade = Linen.kr(gate,doneAction:2);
                     out  = sig*fade*amp.lag(0.2);
                 Out.ar(0, out)
         }).add;
)

a = Synth(\quad, [\freq,400,\amp,1,\gate,1]);
a.set(\gate,0);

Rettangolare

Lo spettro dipende dalla percentuale di Duty cycle sia per quanto riguarda la presenza degli armonici che per quanto riguarda la loro ampiezza. E' generata da Pulse.ar() il cui secondo argomento definisce il duty cycle sotto forma di fattore di moltiplicazione (50% = 0.5).

(
SynthDef(\rect, {arg freq=400,duty=0.1,amp=0,gate=0;
	             var sig,fade,out;
                     sig  = Pulse.ar(freq,duty);
                     fade = Linen.kr(gate,doneAction:2);
                     out  = sig*fade*amp.lag(0.2);
                 Out.ar(0, out)
         }).add;
)

a = Synth(\rect, [\freq,400,\amp,1,\gate,1]);
a.set(\gate,0);

Noises

In SuperCollider (come nella maggior parte dei software audio) ci sono anche oscillatori tabellari dedicati alla generazione di diversi tipi di rumore. In questo paragrafo illustriamo quelli realizzati attraverso funzioni d'onda non deterministiche mentre nel paragrafo dedicato ai segnali di controllo possiamo trovare alcune versioni a bassa frequenza. (LF UGens).

Il timbro di questi segnali cambia a seconda della distribuzione di probabilità utilizzata nella generazione dei valori dei campioni (ampiezze istantanee).

Rumore bianco (White noise)

Il timbro del rumore bianco è caratterizzato da ampiezza costante lungo tutto lo spettro di frequenze.

image not found

(
SynthDef(\white, {arg amp=0,gate=0;
	              var sig,fade;
                      sig  = WhiteNoise.ar;
                      fade = Linen.kr(gate,doneAction:2);
                  Out.ar(0, sig*fade*amp.lag(0.2))
         }).add;
)

a = Synth(\white, [\amp,1,\gate,1]);
a.set(\gate,0);

Rumore rosa (Pink noise)

Il timbro del rumore rosa è caratterizzato da una diminuzione dell'ampiezza spettrale di 3 dB per ottava verso l'acuto e limitato a 8 ottave.

image not found

(
SynthDef(\pink, {arg amp=0,gate=0;
                 var sig,fade;
                     sig  = PinkNoise.ar;
                     fade = Linen.kr(gate,doneAction:2);
                 Out.ar(0, sig*fade*amp.lag(0.2))
         }).add;
)

a = Synth(\pink, [\amp,1,\gate,1]);
a.set(\gate,0);

Rumore marrone (Brown noise)

Il timbro del rumore marrone è caratterizzato da una diminuzione dell'ampiezza spettrale di 6 dB per ottava verso l'acuto.

image not found

(
SynthDef(\brown, {arg amp=0,gate=0;
	              var sig,fade;
                      sig  = BrownNoise.ar;
                      fade = Linen.kr(gate,doneAction:2);
                  Out.ar(0, sig*fade*amp.lag(0.2))
         }).add;
)

a = Synth(\brown, [\amp,1,\gate,1]);
a.set(\gate,0);

Rumore grigio (Gray noise)

Il timbro del rumore grigio è caratterizzato da una amplificazione dell'ampiezza delle basse frequenze.

image not found

(
SynthDef(\gray, {arg amp=0,gate=0;
                 var sig,fade;
                     sig  = GrayNoise.ar;
                     fade = Linen.kr(gate,doneAction:2);
                 Out.ar(0, sig*fade*amp.lag(0.2))
         }).add;
)

a = Synth(\gray, [\amp,1,\gate,1]);
a.set(\gate,0);

Rumore tagliato (Clip noise)

Il timbro del rumore tagliato è simile a quello del rumore bianco dal quale si differenzia per una maggiore intensità in quanto la Peak-to-peak amplitude è sempre massima.

image not found

(
SynthDef(\clip, {arg amp=0,gate=0;
                 var sig,fade;
                     sig  = ClipNoise.ar;
                     fade = Linen.kr(gate,doneAction:2);
                 Out.ar(0, sig*fade*amp.lag(0.2))
         }).add;
)

a = Synth(\clip, [\amp,1,\gate,1]);
a.set(\gate,0);

Rumore impulsivo (Pulse Noise)

Il timbro del rumore impulsivo è caratterizzato dalla percezione dei singoli clicks e dipende dal parametro che specifica la loro densità.

image not found

(
SynthDef(\dust2, {arg dens=30,amp=0,gate=0;
                  var sig,fade;
                      sig  = Dust2.ar(dens);
                      fade = Linen.kr(gate,doneAction:2);
                  Out.ar(0, sig*fade*amp.lag(0.2))
         }).add;
)

a = Synth(\dust2, [\amp,1,\gate,1]);

a.set(\dens,100);
a.set(\dens,3);
a.set(\gate,0)

Rumore caotico (Chaotic Noise)

Il timbro del rumore caotico è caratterizzato dalla non predicibilità dello stesso (se non in modo empirico) in quanto la forma d'onda è definita attraverso funzioni derivate dalla teoria del caos che nell'evoluzione delle variabili dinamiche esibiscono una sensibilità esponenziale rispetto alle condizioni iniziali.

image not found

(
SynthDef(\caos, {arg caos=0.5,amp=0,gate=0;
	             var sig,fade;
                     sig  = Crackle.ar(caos);
                     fade = Linen.kr(gate,doneAction:2);
                 Out.ar(0, sig*fade*amp.lag(0.2))
         }).add;
)
s.scope;
a = Synth(\caos, [\amp,1,\gate,1]);
a.set(\caos,1.5);
a.set(\caos,rrand(1.0,2.0).postln);
a.set(\gate,0);

Rumore periodico (Periodic Noise)

Possiamo scrivere un numero finito di valori pseudocasuali compresi tra 0 e 1 secondo diverse distribuzioni in un Buffer e rileggerli come onda periodica. Otterremo di volta in volta quello che potremmo definire rumore colorato.

image not found

c = FloatArray.rand2(512,1.0);
d = FloatArray.linrand(512,-1.0,1.0);
e = FloatArray.exprand(512,0.0001,2) - 1;
f = 1-FloatArray.exprand(512,0.0001,2);

Buffer.freeAll;
b = Buffer.loadCollection(s,f);
b.plot;

(
SynthDef(\osc_3, {arg buf=0,freq=400,amp=0,pan=0,gate=0,done=2;
                  var sig,env,pann;
                      sig   = OscN.ar(buf, freq);
                      env   = Linen.kr(gate,doneAction:done);
                      pann  = Pan2.ar(sig*amp.lag(2)*env);
                  Out.ar(0, pann)
        }).add;
)

a = Synth(\osc_3, [\buf,b,\freq,400,\amp,1,\pan,0,\gate,1]);
a.set(\freq,rrand(200, 1000),\dur,rrand(0.1,2),\amp,rand(1.0),\pan,rand2(1.0))
a.set(\gate,0);