scide: implement selectionLength for openDocument
[supercollider.git] / HelpSource / Classes / Klank.schelp
blobb428396c03a7938601ca34598c823041dde24adb
2 class:: Klank
3 summary:: Bank of resonators
4 related:: Classes/DynKlank, Classes/Klang
5 categories:: UGens>Generators>Deterministic, UGens>Filters>Linear
8 Description::
10 Klank is a bank of fixed frequency resonators which can be used to
11 simulate the resonant modes of an object. Each mode is given a ring time,
12 which is the time for the mode to decay by 60 dB.
15 classmethods::
17 method::ar
19 argument::specificationsArrayRef
20 A link::Classes/Ref:: to an link::Classes/Array:: of three Arrays:
22 definitionlist::
23 ## frequencies: || An Array of filter frequencies.
24 ## amplitudes: || an Array of filter amplitudes, or nil. If nil, then amplitudes default to 1.0.
25 ## ring times: || an Array of 60 dB decay times for the filters.
27 All subarrays, if not nil, should have the same length.
29 argument::input
30 The excitation input to the resonant filter bank.
32 argument::freqscale
33 A scale factor multiplied by all frequencies at initialization time.
35 argument::freqoffset
36 An offset added to all frequencies at initialization time.
38 argument::decayscale
39 A scale factor multiplied by all ring times at initialization time.
41 discussion::
42 The parameters in code::specificationsArrayRef:: can't be changed after it has been started.
43 For a modulatable but less efficient version, see link::Classes/DynKlank::.
46 Examples::
48 code::
49 { Klank.ar(`[[800, 1071, 1153, 1723], nil, [1, 1, 1, 1]], Impulse.ar(2, 0, 0.1)) }.play;
51 { Klank.ar(`[[800, 1071, 1353, 1723], nil, [1, 1, 1, 1]], Dust.ar(8, 0.1)) }.play;
53 { Klank.ar(`[[800, 1071, 1353, 1723], nil, [1, 1, 1, 1]], PinkNoise.ar(0.007)) }.play;
55 { Klank.ar(`[[200, 671, 1153, 1723], nil, [1, 1, 1, 1]], PinkNoise.ar([0.007, 0.007])) }.play;
58 play({
59         Klank.ar(`[
60                 Array.rand(12, 800.0, 4000.0),          // frequencies
61                 nil,                                                    // amplitudes (default to 1.0)
62                 Array.rand(12, 0.1, 2)                          // ring times
63                 ], Decay.ar(Impulse.ar(4), 0.03, ClipNoise.ar(0.01)))
67 // multi channel expansion:
68 // an array of specs
71 Klank.ar([
72         `[[500, 1078, 1201.5, 1723], nil, [1, 1, 0.5, 0.3]],
73         `[[700, 1071, 1053, 1723], nil, [1, 1, 1, 1]]
74         ], Impulse.ar([2, 2.5], 0, 0.1))
75 }.play
78 // expanding specs
79 { Klank.ar(`[[[800, 6000], 1071, [1153, 8000], 1723], nil, [1, 1, 1, 1]], Impulse.ar([2, 3], 0, 0.1)) }.play;
83 // a synth def that has 4 partials
86 SynthDef(\help_Klank, { arg out=0, i_freq;
87         var klank, n, harm, amp, ring;
89         // harmonics
90         harm = \harm.ir(Array.series(4, 1, 1).postln);
91         // amplitudes
92         amp = \amp.ir(Array.fill(4, 0.05));
93         // ring times
94         ring = \ring.ir(Array.fill(4, 1));
96         klank = Klank.ar(`[harm, amp, ring], {ClipNoise.ar(0.003)}.dup, i_freq);
98         Out.ar(out, klank);
99 }).add;
102 // nothing special yet, just using the default set of harmonics.
103 a = Synth(\help_Klank, [\i_freq, 300]);
104 b = Synth(\help_Klank, [\i_freq, 400]);
105 c = Synth(\help_Klank, [\i_freq, 533.33]);
106 d = Synth(\help_Klank, [\i_freq, 711.11]);
108 a.free;
109 b.free;
110 c.free;
111 d.free;
113 a = Synth(\help_Klank, [\i_freq, 500, \harm, [4, 1, 3, 5, 7]]);
114 a.free;
116 // set geometric series harmonics
117 a = Synth(\help_Klank, [\i_freq, 500, \harm,Array.geom(4, 1, 1.61)]);
118 a.free;
120 // set harmonics, ring times and amplitudes
122 a = Synth(\help_Klank, [
123         \i_freq, 500,
124         \harm, [4, 1, 3, 5, 7],
125         \ring, Array.fill(4, 0.1), // set shorter ring time
126         \amp, Array.fill(4, 0.2) // set louder amps
133 // -- overlap texture
135 SynthDef("help-KlankOverlapTexture",
136 {|out = 0, freqs = #[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], rings = #[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], atk = 5, sus = 8, rel = 5, pan = 0|
137         var e = EnvGen.kr(Env.linen(atk, sus, rel, 1, 4), doneAction:2);
138         var i = Decay.ar(Impulse.ar(Rand(0.8, 2.2)), 0.03, ClipNoise.ar(0.01));
139         var z = Klank.ar(
140                 `[freqs, nil, rings],   // specs
141                 i                                       // input
142         );
143         Out.ar(out, Pan2.ar(z*e, pan));
144 }).add;
146 r = Routine{
147         var sustain = 8, transition = 3, overlap = 4;
148         var period = transition * 2 + sustain / overlap;
149         0.5.wait;                       // wait for the synthdef to be sent to the server
150         inf.do{
151                 Synth("help-KlankOverlapTexture", [
152                         \atk, transition,
153                         \sus, sustain,
154                         \rel, transition,
155                         \pan, 1.0.rand2,
156                         \freqs, {200.0.rrand(4000)}.dup(12),
157                         \rings, {0.1.rrand(2)}.dup(12)
158                 ]);
159                 period.wait;
160         }
162 r.play;
165 r.stop; // stop spawning new synths
169 // -- frequency and decay scaling
171 SynthDef("help-KlankScaling", {|out = 0, freq = 0, rings = #[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], pan = 0|
172         var e = EnvGen.kr(Env(#[1, 1, 0], #[0.4, 0.01]), doneAction:2);
173         var i = Decay.ar(Impulse.ar(0), 0.03, ClipNoise.ar(0.01));
174         var z = Klank.ar(
175                 `[(1..12), nil, rings],                                 // specs (partials, amplitudes, ringtimes)
176                 i,                                                      // input
177                 freq,                                                   // scale to this frequency
178                 0,                                                      // frequency offset
179                 MouseX.kr(0.2, 3)                               // scale decay times
180         );
181         Out.ar(out, Pan2.ar(z*e, pan));
182 }).add;
184 r = Routine{
185         var sustain = 8, transition = 3;
186         var mode = #[0, 2, 4, 5, 7, 9, 11, 12, 14, 16, 17, 19, 21, 23, 24];
187         0.5.wait;                       // wait for the synthdef to be sent to the server
188         inf.do{|i|
189                 Synth("help-KlankScaling", [
190                         \freq, (72 + (mode @@ i)).midicps,
191                         \rings, {0.1.rrand(2)}.dup(12)
192                 ]);
193                 0.2.wait;
194         }
196 r.play;
199 r.stop;
202 // -- overlap texture 2
204 SynthDef("help-KlankOverlapTexture2",
205 {|out = 0, freqs = #[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], rings = #[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], atk = 5, sus = 8, rel = 5, pan = 0|
206         var e = EnvGen.kr(Env.linen(atk, sus, rel, 1, 4), doneAction:2);
207         var i = BrownNoise.ar(0.0012);
208         var z = Klank.ar(
209                 `[freqs, nil, rings],   // specs
210                 i                                       // input
211         );
212         Out.ar(out, Pan2.ar(z*e, pan));
213 }).add;
215 r = Routine{
216         var sustain = 6, transition = 4, overlap = 5;
217         var period = transition*2+sustain/overlap;
218         0.5.wait;                       // wait for the synthdef to be sent to the server
219         inf.do {
220                 Synth("help-KlankOverlapTexture2", [
221                         \atk, transition,
222                         \sus, sustain,
223                         \rel, transition,
224                         \pan, 1.0.rand2,
225                         \freqs, {6000.0.linrand+80}.dup(12),
226                         \rings, {0.1.rrand(3)}.dup(12)
227                 ]);
228                 period.wait;
229         }
231 r.play;
234 r.stop;
237 // -- overlap texture 3
239 SynthDef("help-KlankOverlapTexture3",
240 {|out = 0, freqs = #[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], rings = #[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], pan = 0|
241         var e = EnvGen.kr(Env(#[1, 1, 0], #[18, 3]), doneAction:2);
242         var i = Decay.ar(Impulse.ar(Rand(0.2, 0.6)), 0.8, ClipNoise.ar(0.001));
243         var z = Klank.ar(
244                 `[freqs, 2, rings],     // specs
245                 i                                       // input
246         );
247         Out.ar(out, Pan2.ar(z*e, pan));
248 }).add;
250 r = Routine{
251         0.5.wait;                       // wait for the synthdef to be sent to the server
252         inf.do {
253                 Synth("help-KlankOverlapTexture3", [
254                         \pan, 1.0.rand2,
255                         \freqs, {12000.0.linrand+80}.dup(12),
256                         \rings, {3.rrand(10)}.dup(12)
257                 ]);
258                 3.wait;
259         }
261 r.play;
264 r.stop;