Most recent edit on 2007-07-04 18:42:12 by SuperCollider
Additions:
Passage de Message < Index > Bus
Passage de Message < Index > Bus
Edited on 2007-06-19 16:06:04 by SuperCollider
Additions:
représentation graphique de cet exemple:
Edited on 2007-06-19 15:38:56 by SuperCollider
Additions:
~- un des concepts les moins évidents à appréhender dans Supercollider
- nécessite de la clarté dans le projet
- que l'ordre soit spécifié ou non, chaque node prends une place unique et déterminée dans la chaîne d'exécution
exécuter ce qui suit et regarder la console
- le default_group garantit un emplacement défini pour toute la structure des Nodes, et permet à certaines méthodes de pouvoir se placer en aval,( par exemple pour une analyse ou un traitement globaux, pour une visualisation (scope) [...]
Deletions:
~- un des concepts les moins évidents à apréhender dans Supercollider
nécéssite de la clarté dans le projet
que l'ordre soit spécifié ou non, chaque node prends une place unique et spécifique [redondant?] dans la chaîne d'exécution
executer ce qui suit et regarder la console
- le default_group garantit un emplacement définit à toute la structure des Nodes, et permet à certaines méthodes de pouvoir se placer en aval,( par exemple pour une analyse ou un traitement globaux, pour une visualisation (scope) [...]
Edited on 2007-05-31 22:43:40 by SuperCollider
Additions:
~- à son lancement, le serveur crée un group racine, avec un ID 0, représenté dans le langage par RootNode∞
Deletions:
~- à son lancement, le serveur crée un group racine, avec un ID 0, représenté dans le langage par RootNode
Edited on 2007-05-30 13:21:30 by SuperCollider
Additions:
[groupe de Synths] - > effet -> sortie principale
Group ( [groupe de Synths] ) -> Group ( effet) -> sortie
Deletions:
[groupe de Synths]
> effet
> sortie principale
Group ( [groupe de Synths] )
> Group ( effet)
> sortie
Oldest known version of this page was edited on 2007-05-30 12:49:34 by SuperCollider []
Page view:
ordre d'exécution
- un des concepts les moins évidents à apréhender dans Supercollider
- nécéssite de la clarté dans le projet
- n'est pas associé à l'ordre temporel du passage des messages depuis le client
- lié à l'ordonnancement des Nodes sur le serveur (correspond exactement à l'ordre dans lequel leur sortie est calculée pour chaque cycle de contrôle (blocksize, [spécifier])
- que l'ordre soit spécifié ou non, chaque node prends une place unique et spécifique [redondant?] dans la chaîne d'exécution
- l'ordre d'exécution n'est important que si un synth lit la sortie d'un autre ( avec In.ar)
- soit une source et un effet dans la chaîne d'exécution, la source doit se trouver avant pour être prise en compte par l'effet [...]
source -> effect
Notes sur les Serveurs et le Cibles (Targets)
- sc définit un Serveur par défaut (changeable avec la méthode de classe Server.default), le serveur Local, assigné à la variable globale s
// executer ce qui suit et regarder la console
s === Server.default;
s === Server.local;
Server.default = Server.internal;
s === Server.default;
Server.default = Server.local; // return it to the local server
- à son lancement, le serveur crée un group racine, avec un ID 0, représenté dans le langage par RootNode
- il crée ensuite un default_group, avec l'ID 1: c'est le groupe de base pour tous les Nodes
- par défaut (c.a.d sans spécifier de seveur cible au commandes .load ou .send) le default_group est construit sur le serveur par défaut [...]
- le default_group garantit un emplacement définit à toute la structure des Nodes, et permet à certaines méthodes de pouvoir se placer en aval,( par exemple pour une analyse ou un traitement globaux, pour une visualisation (scope) [...]
Contrôle de l'ordre d'exécution
trois manières:
- message addAction
- déplacement des Nodes
- utilisation de Groupes
Add actions
- utilisation de la méthode addAction sur un Node (Synth, Group, voire Server)
- Syntaxe: Synth(nom, arguments, cible, addAction)
- actions possibles : \addToHead, \addToTail, \addBefore, \addAfter, \addReplace.
- l'action s'applique à la cible
- concernant \addToTail et \addToHead: si la cible est un serveur, le message s'adressera au groupe par défaut de celui-ci.
alternative : méthodes sur la classe Synth
Synth.head(cible, nomDuDef, arguments) //en tête
Synth.tail(cible, nomDuDef, arguments) //en queue
- si la cible est elle-même un Synth, le message s'adresse au groupe de celui-ci
- si la cible est un Serveur, le message s'adresse au groupe par défaut de celui-ci
- si la cible est 'nil', le message s'adresse au groupe par défaut du Serveur par défaut
Synth.before(cible, nomDuDef, argument)
Synth.after(cible, nomDuDef, argument)
Synth.replace(cible, nomDuDef, argument )
- la création d'un Synth sans méthode addAction assume la methode addAction par défaut (tête du groupe par défaut)
Déplacement des Nodes:
- changement à postériori d'un emplacement dans l'arborescence
.moveBefore
.moveAfter
.moveToHead
.moveToTail
~fx = Synth.tail(s, "fx");
~src = Synth.tail(s, "src"); // l'effet est inactif,il est avant la source
~src.moveBefore(~fx); // placement de l'effet **après** la source
Groups
- le déplacement d'un groupe implique le déplacement des Nodes qu'il contient
Group 1 -> Group 2
Dans la configuration ci-dessus, tous les synths de Group1 s'éxécutent avant ceux de Group2
permet un contrôle plus facile de l'ordre
structure
- déterminer la structure, et utiliser les groupes pour modèliser cette
configuration courante
- ensemble de Nodes
- processés dans un effet
[groupe de Synths]
> effet
> sortie principale
devient
Group ( [groupe de Synths] )
> Group ( effet)
> sortie
- dans ce contexte, on peut manipuler, ajouter, enlever des synths, avec la garantie qu'ils sont pris en compte dans l'effet.
Exemple
- modulation d'un paramètre avec un synth de control-rate
s.boot;
(
l = Bus.control(s, 1); // control bus pour LFO
b = Bus.audio(s, 2); // sépare la chaine src->fx d'autres chaînes similaires
~synthgroup = Group.tail(s);
~fxgroup = Group.tail(s);
// synthgroup --> fxgroup, depuis le group par défaut de **s**
// quelques Synthdef
SynthDef("order-of-ex-dist", { arg bus, preGain, postGain;
var sig;
sig = In.ar(bus, 2);
sig = (sig * preGain).distort;
ReplaceOut.ar(bus, sig * postGain);
}).send(s);
SynthDef("order-of-ex-pulse", { arg freq, bus, ffreq, pan, lfobus;
var sig, noteLen;
noteLen = In.kr(lfobus, 1);
sig = RLPF.ar(Pulse.ar(freq, 0.2, 0.5), ffreq, 0.3);
Out.ar(bus, Pan2.ar(sig, pan)
* EnvGen.kr(Env.perc(0.1, 1), timeScale: noteLen, doneAction: 2));
}).send(s);
SynthDef("LFNoise1", { arg freq, mul, add, bus;
Out.kr(bus, LFNoise1.kr(freq, mul:mul, add:add));
}).send(s);
)
// Placement du LFO
~lfo = Synth.head(s, "LFNoise1", [\freq, 0.3, \mul, 0.68, \add, 0.7, \bus, l.index]);
// Placement des effets
~dist = Synth.tail(~fxgroup, "order-of-ex-dist", [\bus, b.index, \preGain, 8, \postGain, 0.6]);
// transfert de l'ensemble vers la sortie principale, avec mise à niveau
// exécution à la queue du groupe défaut de **s** (noter que Function.play peut prendre l'argument *addAction*)
~xfer = { Out.ar(0, 0.25 * In.ar(b.index, 2)) }.play(s, addAction: \addToTail);
//Démarrage de la routine:
(
r = Routine({
{
Synth.tail(~synthgroup, "order-of-ex-pulse",
[\freq, rrand(200, 800), \ffreq, rrand(1000, 15000), \pan, 1.0.rand2,
\bus, b.index, \lfobus, l.index]);
0.07.wait;
}.loop;
}).play(SystemClock);
)
~dist.run(false); //vérification de l'effet
~dist.run(true);
//nettoyage
(
r.stop;
[~synthgroup, ~fxgroup, b, l, ~lfo, ~xfer].do({ arg x; x.free });
currentEnvironment.clear; // nettoyage des variable d'environnement
)
Messaging Style
- l'exemple précédent utilise les abstractions du langage pour le passage de message
- on peut réaliser l'équivalent en passage direct de message : voir NodeMessaging∞ et Server-Command-Reference∞