Mes explications pour le fonctionnement de la reverb sont-elles correctes?

J’ose poser ma question en français, espérant qu’un certain nombre d’entre vous réussirons à la comprendre. Si vous voulez me répondre en anglais, pas de problème.

Voici un code créant un petit synthé FM, une reverb et un motif. J’ai mis pas mal d’explication concernant la reverb, et un peu concernant le motif.

Je ne suis pas sûr d’avoir tout bien compris au niveau de la reverb car j’ai copié l’exemple quelque part donc je ne suis pas l’inventeur de cette reverb. Dites-moi si mes explications sont correctes.

Autrement si vous avez des idées d’améliorations pour le code concernant le synthé FM et le motif, je suis preneur. De même, j’aimerais bien apprendre à faire des reverb peut-être plus raffinée que celle-ci. Le code est un peu long, car il y a pas mal d’explications.

s.boot;
// un peu de nettoyage et créons en même temps un canal audio pour la reverb
(
s.newBusAllocators;
~vbus = Bus.audio(s, 2);
s.freeAll;
)

// Reprenons notre petit synthétiseur FM :

(
SynthDef.new(\fm, {
	arg freq=500, modHz=100, modAmp=0.2, gate=1.0, atk=0.01, rel=1.0, amp=0.2, pan=0.0, fxsend=(-25);
	var car, mod, env, env2;
	env = EnvGen.kr(Env.perc(atk, rel), gate: gate);
	env2 = EnvGen.kr(Env.perc(0.01, 0.5), gate: gate);
	mod = SinOsc.ar(freq:modHz, mul:modAmp) * env2;
	car = SinOsc.ar(freq:[freq + mod, freq + 8 + mod]) * env * amp;
	Out.ar(0, car);
	Out.ar(~vbus, car * fxsend.dbamp);
}).add;
)

// On ajoute maintenant la définition de la reverb, je mets quelques explications pour rendre les choses plus claires. J'espère que mes explications sont bonnes :

(
SynthDef(\reverb, {
	// On déclare d'abord les arguments qui vont nous servir dans la définition de cette reverb
		arg in=0, out=0, dec=8, lpf=1500;
	// On déclare la variable sig qui va nous servir à construire notre signal
		var sig;
	// Le signal est d'abord fait de l'entrée stéréo assignée, dans la définition c'est l'audio gauche, mais par la suite on utilisera le bus que nous avons créé pour la reverb un peu plus haut. On fait la somme des deux signaux pour avoir un traitement mono (demande moins de puissance de calcul).
		sig = In.ar(in, 2).sum;
	// On crée d'abord un léger délai, avec une petite valeur
		sig = DelayN.ar(sig, 0.03, 0.03);
	// On rajoute 32 délai pour chaque entrée avec des valeurs différentes ce qui simule une réverbération.
		sig = CombN.ar(sig, 0.1, {Rand(0.01,0.099)}!32, dec);
	// On répartit ces 32 délais sur 2 cannaux stéréo :
		sig = SplayAz.ar(2, sig);
	// On applique un filtre passe bas au signal :
		sig = LPF.ar(sig, lpf);
	// On rajoute plusieurs délai : j'ai du mal à comprendre exactement ce qui se passe !
		4.do{sig = AllpassN.ar(sig, 0.1, {Rand(0.01,0.099)}!2, 3)};
	// On applique à nouveau un filtre passe bas au signal ;
		sig = LPF.ar(sig, lpf);
	// On évite d'avoir un DC bias comme résultat donc on l'élimine. Voir l'article wikipedia suivant : https://en.wikipedia.org/wiki/DC_bias
		sig = LeakDC.ar(sig);
	// On envoie le signal calculé à la sortie audio, qui ici est le bus gauche, mais comme le signal est stéréo (ligne 39), il sortira sur la gauche et sur la droite en stéréo.
		Out.ar(out, sig);
	}).add;
)

// Pour avoir un son de ce nouveau synthétiseur qui s'appelle \fm on tape la commande suivante, qui lance le synthétiseur avec les commandes par défaut inscrites dans la définition du synthé.

Synth(\fm);

// Pour avoir la reverb il faut d'abord la lancer !
Synth(\reverb, [\in, ~vbus]);

// Et maintenant si on refait la commande qui lance notre petit synthé fm on a la reverb. L'ordre d'exécution des commandes est donc très important.

Synth(\fm);

// Avançons dans l'apprentissage de la compostion via Supercollider

// Prenons l'habitude de composer à plusieurs voix, en nommant les voix comme on le fait en musique classique.

(
/* On crée deux collections : une pour les hauteurs de notes, une autre pour la durée des notes.

De manière conventionnelle, je représente chaque hauteur de note par la convention utilisée pour les nommer. La fondamental est 1, la quinte 5, la quarte 4, l'octave 8. Cela permet de bien s'y repérer pour composer.

Je choisis aussi d'écrire les noires en mettant 8 au lieu de 1 par défaut dans Supercollider, cela permet d'avoir des croches avec 4 et des doubles croches avec 2. Cela permet d'écrire plus facilement la durée exactement en dessous de la hauteur de la note. Pour mieux lire musicalement ce que l'on écrit.

Je mets enfin des espaces supplémentaires pour faire apparaître visuellement la durée de chaque notes, absence d'espace signifiant ici que la durée est équivalente à une double croche. Les espaces ne sont pas interprété par Supercollider quand on tape des chiffres donc, le résultat est juste visuel et n'apparaîtra pas dans la collection créee.*/

~alto1 =     [1      ,5,4,6,5,8      ,7,5,6,5,4,1,5       ];
~altodur1 =  [4      ,2,2,2,2,4      ,2,2,2,2,2,2,8       ];
// On inverse l'ordre des notes
~alto2 = ~alto1.reverse;
// Crée une nouvelle collection à partir de la première en transposant de manière aléatoire chaque note soit d'une tierce soit d'une quinte, soit en diminuant d'une tierce, mais en restant dans la gamme.
~alto3 = ~alto1.collect({ arg item, i; item + [3,5,-3].choose });
// On crée une nouvelle collection de notes contenant les 3 collections de notes créées plus la troisième inversée ;
~alto = ~alto1++~alto2++~alto3++~alto3.reverse;
(
Synth(\reverb, [\in, ~vbus]);
p = Pbind(
	\instrument, \fm,
	// Je multiplie le tempo par 16 pour avoir des noires à 120 BPM avec la convention que j'ai choisie d'appliquée lignes 70-71.
	\tempo, 16,
	// On transpose la collection de note d'un degré bers le bas, car dans Supercollider la convention c'est d'avoir la fondamentale représentée par 0. Puis, on répète 4 fois la collection de note créée ;
	\degree, Pseq(~alto-1,4),
	\dur, Pseq(~altodur,inf),
	\modHz, Pexprand(300.0,7000,inf),
	\modAmp, Pwhite(20, 100.0),
	\amp, Pexprand(0.1, 0.3),
	\atk, Pexprand(0.001, 0.005),
	\rel, Pexprand(0.2, 2),
	\fxsend, Pexprand(-60, -20),
);
)
)
~pl = p.play;


// Pour voir les événements choisis à chaque fois il suffit de faire :
~pl = p.trace.play;

// Commande qui permet d'arrêter la séquence sans utiliser la coupure générale.
// Attention si vous faites la commande stop (la coupure générale) avec le raccourci prévu dans Supercollider, il faudra relancer la reverb.

~pl.stop;