Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / HelpSource / Tutorials / JITLib / jitlib_fading.schelp
blob11720e8286bcb8e8ec01738b6df26d1cf90930c5
1 title:: jitlib_fading
2 summary:: Fade envelope generation and crossfading
3 categories:: Libraries>JITLib>Tutorials
4 related:: Overviews/JITLib
6 link::Classes/NodeProxy:: ( link::Classes/ProxySynthDef:: ) looks for inner envelopes in your definition function to find out whether a fade envelope is needed or not. In case there is no other inner possibility of freeing the synth, either
8 list::
9 ## link::#a)_automatic_fade_envelope_generation#a):: a fade envelope is created (audio / control rate output)
10 ## link::#b)_automatic_free_instead_of_crossfade#b):: the synth is freed directly with no fading (scalar output or doneAction 1)
12 ## link::#c)_custom_fade_envelope#c):: if you provide a gate arg and a doneAction 2 to your ugenGraph function, this is supposed to be a fade envelope for the synth
14 ## link::#d)_synthdef_name_assignment#d):: if a synthdef name is used, case link::#c)_custom_fade_envelope#c):: is supposed
17 ... so in most cases, there is not much to worry about, just these two points ar important, if one wants to use a self releasing synth or a different out ugen:
19 list::
20 ## link::#e)_own_free_responsibility#e):: own responsibility: if the function creates a ugengraph that can be freed by trigger or other things, it waits for this action instead of the node proxy freeing the synth.
22 ## link::#f)_own_output_responsibility#f):: own out channel with 'out' arg: the control ugen with the name 'out' is set to the output channel number of the proxy.
25 code::
26 p = ProxySpace.push(s.boot);
28 ~out.play;
30 // note that you can use this functionality also when using ProxySynthDef directly:
32 d = ProxySynthDef("test", { arg freq=440; SinOsc.ar(freq) }).send(s);
33 s.sendMsg("/s_new", "test", 1980, 1, 1, \freq, 340);
34 s.sendMsg("/n_set", 1980, \freq, 240);
35 s.sendMsg("/n_set", 1980, \fadeTime, 4);
36 s.sendMsg("/n_set", 1980, \gate, 0);
39 section::a) automatic fade envelope generation
41 code::
42 // no inner envelope and audio / control rate output
44 ~out = { PinkNoise.ar([1,1]*0.1) };
48 ~kout = { PinkNoise.kr([1,1]*0.1) };
52 section::b) automatic free instead of crossfade
54 code::
55 // inner envelope that cannot free the synth, the synth is freed when a new
56 // function is assigned.
58 ~out = { arg t_trig; EnvGen.kr(Env.asr, t_trig) * PinkNoise.ar([1,1]) };
60 ~out.group.set(\t_trig, 1);
63 ~out = { arg t_trig; EnvGen.kr(Env.asr, t_trig) * SinOsc.ar([1,1]*400) };
65 ~out.group.set(\t_trig, 1);
68 // for a scalar output also no fade env is created, but the synth is freed (without fading)
70 ~out = { Out.ar(0, SinOsc.ar(Rand(440,550),0,0.2)) };
74 section::c) custom fade envelope
76 code::
77 // when a gate arg is provided, and the env can free the synth, this envelope
78 // is supposed to be the fade envelope for the synth: no extra fade env is created.
80 ~out = { arg gate=1; EnvGen.kr(Env.asr, gate, doneAction:2) * 0.2 * SinOsc.ar([1,1]*Rand(440,550)) };
84 section::d) SynthDef name assignment
86 code::
87 // if a symbol is used as input, the defname of a def on the server is supposed
88 // to represent a SynthDef that has a gate, an out input and can free itself.
90 ~out = \default;
93 // this is the minimal requirement arguments for such a use (similar to Pbind)
95 SynthDef("test", { arg gate=1, out;
96         Out.ar(out, Formant.ar(300, 200, 10) * EnvGen.kr(Env.asr, gate, doneAction:2))
97 }).send(s);
100 // you can also provide a fadeTime arg, whic is set by the proxy:
102 SynthDef("test", { arg gate=1, out, fadeTime=1;
103         Out.ar(out,
104                 Formant.ar(Rand(20,40), 600, 10, 0.2)
105                 * EnvGen.kr(Env.asr(fadeTime,1,fadeTime), gate, doneAction:2)
106         )
107 }).send(s);
110 ~out = \test;
111 ~out.fadeTime = 3;
114 note::
115 the strong::number of channels:: is your own responsibility when using symbols, as a symbol carries no channel information! (in all other cases the number of channels is wrapped or expanded to fit the proxy)
118 code::
119 // if the synthdef has a fixed duration envelope, there is a FAILURE /n_set Node not found message.
120 // with no further significance
122 SynthDef("test", { arg gate=1, out;
123         Out.ar(out,
124                 Formant.ar(Rand(20,40), 600, 10, 0.6)
125                 * EnvGen.kr(Env.perc, gate, doneAction:2)
126         )
127 }).send(s);
130 ~out = \test;
133 section::e) own free responsibility
135 code::
136 //inner envelope that can free the synth, no extra fade env is created:
138 ~out = { arg t_trig; EnvGen.kr(Env.asr, t_trig, doneAction:2) * PinkNoise.ar([1,1]) };
140 ~out.group.set(\t_trig, 1); //end it
142 ~out.send; //start a new synth
143 ~out.group.set(\t_trig, 1); //end it again
146 // if there is a ugen that can free the synth, no extra fade env is created either,
147 // but it supposes the synth frees itself, so if a new function is assigned it does
148 // not get freed.
150 ~out = { arg t_trig;
151         FreeSelf.kr(t_trig);
152         PinkNoise.ar([1,1]*0.3);
155 ~out.group.set(\t_trig, 1);
158 section::f) own output responsibility
160 code::
161 // the arg name 'out' can be used to output through the right channel.
162 // of course with this one can get problems due to a wrong number of channels
163 // or deliberate hacks.
165 //left speaker
167 ~out = { arg out;
168         OffsetOut.ar(out, Impulse.ar(10,0,0.1))
172 //both speakers
174 ~out = { arg out;
175         OffsetOut.ar(out, Impulse.ar([10, 10],0,0.1))
179 //this plays out into another adjacent bus: this is a possible source of confusion.
181 ~out = { arg out;
182         OffsetOut.ar(out, Impulse.ar([10, 10, 10],0,0.1))