// 18
// Nathaniel Virgo
(
play{
    p = PinkNoise.ar(1!2);
    BRF.ar(
        p + Blip.ar(p+2,400),
        150,
        2,
        0.1
    )
    +
    LPF.ar( FreeVerb2.ar( *LPF.ar( p + 0.2 * Dust.ar( 0.1 ), 60) ++ [ 1, 1, 0.2, 1e4 ]).tanh, 2000)
}
)





(1!2).postln -> [ 1, 1 ]
PinkNoise *ar (mul: 1.0, add: 0.0)
PinkNoise.ar([1,1])

Genera rumore rosa il cui spettro decade in potenza di 3 dB per ottava, il che fornisce uguale potenza nell'arco di ciascuna ottava. Questa versione ha un limite di banda di 8 ottave.

Al rumore rosa viene aggiunto un segnale

Blip.ar(freq: 440.0,  numharm: 200.0,  mul: 1.0,  add: 0.0)
che è un segnale di impulsi limitato in banda; il numero di armoniche nel nostro caso è settato a 400; la frequenza è data dal doppio PinkNoise; quella specie di rumore di gocce di acqua che cadono che si sente è dovuto all'UGen Blip.ar;

il segnale risultante è fatto passare in un filtro risonante rifiuta banda, BRF.ar(in: 0.0, freq: 440.0, rq: 1.0, mul: 1.0, add: 0.0)



BRF.scopeResponse

a questo segnale è aggiunto un secondo segnale :




















LPF.ar( FreeVerb2.ar( *LPF.ar( p + 0.2 * Dust.ar( 0.1 ), 60) ++ [ 1, 1, 0.2, 1e4 ]).tanh, 2000)

Un "*" prima di un array all'interno di una funzione divide gli elementi dell'array e li passa agli args, nel nostro caso alla UGen FreeVerb2.ar. Diventa più chiaro facendo questo con il metodo Array.with che genera un nuovo array e prevede elementi separati.

Array.with(*LPF.ar (PinkNoise.ar (1! 2) + 0.2 * Dust.ar (0.1), 60) ++ [1, 1, 0.2, 1e4])
-> [ a LPF, a LPF, 1, 1, 0.2, 10000.0 ]

quindi la UGen avra questi args : FreeVerb2.ar(in: LPF,  in2: LPF,  mix: 1,  room: 1,  damp: 0.2,  mul: 10000.0,  add: 0.0)

questo segnale genera un forte boato, 1 volta ogni 10 secondi circa, dovuto all'impulso creato dal Dust moltiplicato per il Rumore Rosa;

La precedenza sinistra-destra di SC provoca l'aggiunta di un offset di 0,2 (al Rumore Rosa stereo) prima della moltiplicazione con l'impulso Dust.
La funzione sigmoide tanh mantiene il segnale tra -1 e + 1;

Per quanto riguarda l'offset di 0,2. Ho solo un presupposto: il file di aiuto di PinkNoise dice:

NOTA: è stato osservato che i valori prodotti da questa UGen sono molto probabilmente tra -0,65 e +0,81 circa (prima di essere moltiplicati per mul).

Quindi potrebbe essere che l'intenzione fosse quella di mantenere il segnale all'incirca al di sotto di 1, con probabilità molto alta.

// Modo per attivare e esplorare le Eccezioni con la GUI

Exception.debug = true;

// Metodo per salvare l'immagine del Plot

p= {BRF.ar( PinkNoise.ar(1!2) + Blip.ar(PinkNoise.ar(1!2)+2,400), 150, 2, 0.1) }.plot(10);
i = Image.fromWindow(p.parent, p.interactionView.bounds);
i.write("~/concat.png".standardizePath);
i.free

// Metodo per tracciare una Synth

(
SynthDef(\resonz, { |out, freq = 440|
    var    sig, ffreq;
    sig = PinkNoise.ar(1!2);
    Out.ar(out, FreeVerb2.ar( *LPF.ar( sig + 0.2 * Dust.ar( 0.1 ), 60) ++ [ 1, 1, 0.2, 1e4 ]).tanh, 0.1)
}).send(s);

)

a = Synth(\resonz);
a.trace;

// Metodo per capire come è composto un segnale

sig = PinkNoise.ar(1 ! 2).postln;
sig = LPF.ar (sig + 0.2 * Dust.ar(0.1), 60).postln;
sig = (sig ++ [1, 1, 0.2, 1e4]).postln;
sig = FreeVerb2.ar(*sig).postln;

Reverse Engineering di un sc-tweet di Rukano

play{a[1,1.01,2,2.02,3.5,4.01,5.501];SinOsc.ar(Duty.kr(0.2,0,Dseq([10,11,0,12.2,0,0,10,0]+39,inf).midicps)*(a++(a*2))).sum!2/10}//DAF #sc

Un Oscillatore Sinusoidale, SinOsc.ar, la cui frequenza è estratta dalla lista di Dseq dall'UGen Duty ogni 0.2 secondi; il tutto è moltiplicato per 14 valori ottenuti concatendando l'array di 7 valori "a" al doppio di se stesso; quindi per ogni elemento estratto ogni 0.2 secondi da Duty.kr abbiamo 14 Sinusoidi che poi vengono sommate in un unico segnale; il segnale ottenuto viene poi duplicato sul canale sinistro e destro dell'uscita; l'ampiezza è divisa per 10;





















SinOsc.ar(freq: 440,  phase: 0.0,  mul: 1.0,  add: 0.0)

Duty.kr(dur: 1.0,  reset: 0.0,  level: 1.0,  doneAction: 0)

ogni "dur" secondi, viene richiesto un valore da ogni Ugen nella lista; nel nostro caso ogni 0.2 secondi, viene richiesto un elemento della lista ([10,11,0,12.2,0,0,10,0]+39).midicps che viene generato dalla Ugen Dseq;





















Dseq.new(list, repeats: 1)

Generatore di sequenze; genera un valore appartenente alla lista, ogni volta che viene interrogato da Ugen tipo Demand, Duty, Drand, ecc.

{a[1,1.01,2,2.02,3.5,4.01,5.501];SinOsc.ar(Duty.kr(0.2,0,Dseq([10,11,0,12.2,0,0,10,0]+39,inf).midicps)*(a++(a*2)))}.plot(10)





















(a++(a*2))
[ 1, 1.01, 2, 2.02, 3.5, 4.01, 5.501, 2, 2.02, 4, 4.04, 7.0, 8.02, 11.002 ]



play{AY.ar((Hasher.ar(Latch.ar(AY.ar((1..3)!2),Impulse.ar([7/3,1])))*337+317).round(73),0,LFNoise2.ar(3,1/3,1/3))/7}//#supercollider

AY.ar(tonea: 1777,  toneb: 1666,  tonec: 1555,  noise: 1,  control: 7,  vola: 15,  volb: 15,  volc: 15,  envfreq: 4,  envstyle: 1,  chiptype: 0,  mul: 1,  add: 0)

Emula lo strumento AY-3-8910 (a.k.a. the Yamaha YM2149) a tre voci, tre suoni chip.

i tre suoni chip :

tonea : (Hasher.ar(Latch.ar(AY.ar((1..3)!2),Impulse.ar([7/3,1])))*337+317).round(73)
toneb : 0
tonec : LFNoise2.ar(3,1/3,1/3)

Latch.ar(in: 0.0,  trig: 0.0)

Il Latch mantiene l'input quando viene triggherato e genera zero all'inizio fino a quando non viene triggherato; nel nostro caso è triggherato da un doppio generatore di impulsi; quindi probabilmente il Latch campiona due valori secondo frequenze diverse;

questo è il segnale che viene campionato sui due canali stereo secondo il trig dei due impulsi;

{AY.ar((1..3))}.plot





































{Latch.ar(AY.ar((1..3)!2),Impulse.ar([7/3,1]))}.plot





















{(Hasher.ar(Latch.ar(AY.ar((1..3)!2),Impulse.ar([7/3,1])))*337+317).round(73)}.plot(10)





















Hasher.ar(in: 0.0,  mul: 1.0,  add: 0.0)

L'Hasher è un generatore Hash, che genera valori tra -1 e 1 a seconda dell'input che riceve secondo una funzione Hash; lo stesso valore di input genererà lo stesso valore hash in output; il segnale di input non ha bisogno di essere nel range di -1 e 1.


Impulse.ar(freq: 440.0,  phase: 0.0,  mul: 1.0,  add: 0.0)

Genera in output impulsi non limitati in banda; in teoria quindi se si superano i 22050 Herz di frequenza avremo un mirror nello spettro in frequenza?

round

round(a, b)
a round: b
a.round(b)

Arrotonda al più vicino multiplo di b;

LFNoise2.ar(freq: 500.0, mul: 1.0, add: 0.0)

{LFNoise2.ar(3,1/3,1/3)}.plot(10)





















Genera valori casuali interpolati quadraticamente ad una velocità data dalla divisione intera più vicina della frequenza di campionamento freq.