SuperCollider : JItLib

SuperCollider :: Categories :: PageIndex :: RecentChanges :: RecentlyCommented :: Login/Register

JITLib

(Just In Time Library, créé et maintenu par Julian Rhohurber)


Cette librairie est destinée à fournir un environnement facilitant le 'livecoding', en donnant des emplacements abstraits (proxies), pouvant êtres remplis, modifiés, utilisés pour le calcul pendant l'exécution. Par exemple, il devient simple de changer la source d'un filtre ou le filtre d'une source en une seule ligne.

JITlib est construit autour de notions fondamentales, comme le proxy, et l'environnement.


Les environnements

un environnement (Environment) est un dictionnaire non ordonné, associant une clef ou entrée unique à une valeur
Il existe par défaut au lancement du langage un Environnement : currentEnvironment
s = Server.local.boot;   // on lance le serveur (l'environnement par défaut)
a = {SinOsc.ar(200,0,0.1)}.play;
~b = {SinOsc.ar(220,0,0.1)}.play;

currentEnvironment.dump;

=> Environment[ (b -> Synth("temp__1867963701" : 1000)) ]


Seule la variable ~b (le tilde est en fait une entrée du dictionnaire) fait partie de l'environnement courant

Si l'on veut maintenant appliquer un effet à ~b, le plus simple est de l'arrêter et de modifier sa définition:
~b.stop;  // ne marche pas, il faut arrêter la synthèse (ou arrêter le noeud du graphe en connaissant son index)
s.sendMsg(\n_free, no_index)  // la syntaxe devient compliquée
~b = {Clip.ar(SinOsc.ar(220, 0, 0.1), -0.07, 0.07)}.play;  // nouvelle définition de ~b


Essayons avec JITLib.
On lance le ProxySpace, propre à JITLib :

n = ProxySpace.push(s);
n.fadeTime_(3);  // On peut définir une durée de transition pour les changements
~b = {SinOsc.ar(220,0,0.1)};  // La première définition d'une variable définit si la sortie est mono, stéréo, n-canaux, et son échantillonnage est de type audio (ar) ou contrôle (kr).
~b.play;
~b = {Clip.ar(SinOsc.ar([220,222], 0, 0.1), -0.07, 0.07)};
~b.clear;
~b = {SinOsc.ar([220,222],0,0.1)};



NodeProxy

Le but de l'utilisation d'un proxy dans le cadre du "live coding" est de pouvoir lancer des opérations sans que les membres soit nécessairement existants, autrement dit de créer ou de changer une structure , de la remplir ensuite, et de pouvoir aussi changer ses membres, le tout sans stopper la synthèse .
// boot the server
s.boot;

/* création de deux proxies sur le serveur, vitesse audio, deux canaux.
(note: la vitesse et le nombre de canaux sont les deux paramètres statiques des NodeProxys. Ils ne peuvent plus êtres changés après leur création.)
*/

y = NodeProxy.audio(s, 2);
z = NodeProxy.audio(s, 2);

// calcul sur les proxies
z.play; //z est  juste un place holder
z.source = y.sin * 0.2;
y.source = { Saw.ar([300, 301], 4*pi) };
y.source = 0;
y.source = { Pulse.ar([400, 401], 0.1)};
y.source;

//libération des bus
y.clear;
z.clear;

// Un NodeProxy peut contenir plusieurs objets, leur index détermine leur ordre d'exécution sur le serveur.
y = NodeProxy.audio(s, 2);
y.play;

y[0..8] = { Resonz.ar( WhiteNoise.ar(LFClipNoise.kr(8, 10, 10)), exprand(1000, 5000) * LFNoise2.kr(1, {0.1.rand}!2).midiratio, 0.001).softclip}
//on peut utiliser un ProxySpace pour faciliter la création des NodeProxys
y.objects[2];
y.source;

ProxySpace

Un ProxySpace fournit un environnement pouvant contenir, et faciliter la manipulation de plusieurs NodeProxys.

(
s = Server.local;
s.boot;
p = ProxySpace.push(s);
)

Important : p est un Environement. Après l'instanciation ci-dessus (avec la méthode .push),il a remplacé currentEnvironment
p.dump;
currentEnvironment.dump;
//création d'un NodeProxy dans ce contexte;
~out;

NB: le nom ~out est arbitraire, ce pourrait être ~gudule sans autre spécification, sc crée un NodeProxy sans vitesse définie, et sans taille (nombre de canaux) définie;
~out = {SinOsc.ar([300, 302], 0, 0.2)};
~out;

la vitesse et la taille du NodeProxy sont déduits de la fonction :


Important: ces caractéristiques ne changeront plus: l'affectation d'une fonction valide à ~out a fixé la vitesse et la taille :
~out = {SinOsc.kr(100, 0 , 0.1)}
~out; // toujours deux canaux, la vitesse kr est traduite pour s'adapter à la vitesse audio

//la suite reprends la structure du fichier "proxyspace examples"

//lancement du 'monitoring

~out.play;

//affectation

~out = { RLPF.ar(Pulse.ar(40), {LFNoise0.kr(8).range(40, 200)}!2).softclip };
~out = { RLPF.ar(Pulse.ar(40*LFNoise0.kr(8, 0.3!2).midiratio, LFNoise0.kr(8).range(0.01, 0.99)), {LFNoise0.kr(8).range(40, 200)}!2).softclip };
~out = { Mix.ar(Pan2.ar(Resonz.ar(PinkNoise.ar(30), ((1..16)*[40, 47.57].choose).scramble[..4], LFNoise0.kr(8).range(0.0001, 0.005)), LFClipNoise.kr(8)) )};
p.fadeTime_(4);
// settings
p.fadeTime_(0);
/*
Les fonctions peuvent prendre des arguments (pour les UGens de vitesse de contrôle, kr), et permettre ainsi des modifications extérieures du graphe.
*/

~out = { | rate=2, nb = 5| Resonz.ar(PinkNoise.ar(6), Hasher.kr(LFSaw.kr(rate, mul: nb).round(1)).range(50, 2000), 0.01)};
~out.set(\rate, 0.5, \nb, 7);
~out.set(\rate, 1, \nb, 3);

~souris = {MouseX.kr(0.2, 2)};
~out.map('rate', ~souris);

~out = {SinOsc.ar(200,mul: 0.1)};
~out.add({SinOsc(220,mul:0.1)});
~out[0] = {SinOsc(600,mul:0.1)}

référencement entre proxies
un NodeProxy peut être intégré dans un autre, en temps qu'UGen, et doit donc prendre une méthode indiquant sa vitesse
~lfo = { LFNoise2.kr(30, 300, 500) };
~out = { SinOsc.ar(~lfo.kr, 0, 0.15)  };
~out = { SinOsc.ar(~lfo.kr * [1, 1.2], 0, 0.1) * Pulse.ar(~lfo.kr * [0.1, 0.125], 0.5) };
~lfo = { LFNoise1.kr(30, 40) + SinOsc.kr(0.1, 0, 200, 500) };
~out = { SinOsc.ar(~lfo.kr * [1, 1.2], 0, 0.1)  };
~lfo = 410;

opérations sur les proxies
[à continuer]
placeholders in sc jitlib_basic_concepts_01 referencing and environments jitlib_basic_concepts_02 internal structure of node proxy jitlib_basic_concepts_03 timing in node proxy jitlib_basic_concepts_04 tutorials: proxyspace_examples

There are no comments on this page. [Add comment]

Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by Wikka Wakka Wiki 1.1.6.3
Page was generated in 0.2066 seconds