scel: install files to site-lisp/SuperCollider
[supercollider.git] / HelpSource / Classes / Stream.schelp
blob8d85b8a6226d04514a61576a7d81cfe3078ac3a6
1 class:: Stream
2 summary:: Stream is the base class for classes that define streams
3 related:: Classes/Routine, Classes/FuncStream, Classes/EventStreamPlayer
4 categories:: Streams-Patterns-Events
6 description::
8 Stream is an abstract class that is not used directly. The following attempts to document some aspects of the use of Streams for music generation.
10 subsection::Overview
12 A Stream represents a sequence of values that are obtained incrementally by repeated strong::next:: messages. A Stream can be restarted with a strong::reset:: message. (Not all streams actually implement reset semantics.)
14 The class link::Classes/Object:: defines strong::next:: to return the object itself. Thus every object can be viewed as a stream and most simply stream themselves.
16 In SuperCollider, Streams are primarily used for handling text and for generating music.
18 subsection::FuncStream(nextFunction, resetFunction)
20 A link::Classes/Function:: defines a stream consisting of the Function itself, a link::Classes/FuncStream:: defines a stream that consists of emphasis::evaluations:: of its nextFunction.
22 code::
23 // Example 1: a Function vs. a FuncStream
25         f = { 33.rand };
26         x = FuncStream(f);
27         10.do({ [f.next, x.next].postln });
31 code::
32 // Example 2: the reset function
34         f = { 33.rand };
35         x = FuncStream(f, {thisThread.randSeed_(345)});
36         x.reset;
37         10.do({ [f.next, x.next].postln });
38         x.reset;
39         10.do({ [f.next, x.next].postln });
43 subsection::Routine(nextFunction, stacksize)
45 In a link::Classes/FuncStream::, the nextFunction runs through to completion for each element of the stream. In a link::Classes/Routine::, the nextFunction returns values with strong::yield:: and resumes execution (when it receives a strong::next:: message) at the expression following the yield. This allows a sequence of expressions in the function definition to represent a sequence of distinct events, like a musical score.
47 code::
48 // example
50         x = Routine({
51                 1.yield;
52                 2.yield;
53                 3.yield;
54         });
55         4.do({ x.next.postln });
59 Once the nextFunction completes execution, the Routine simply yields nil repeatedly. Control structures (such as strong::do:: or strong::while::) can be used within the nextFunction in a manner analogous to repeat marks in a score.
61 code::
62 // example
64         x = Routine({
65                 4.do({
66                         [1,2,3,4].do({ arg i; i.yield; });
67                 });
68         });
69         17.do({ x.next.postln });
73 subsection::Playing streams
75 Because streams respond like functions to the value message, they can be used as a scheduling task.
77 code::
78 // compare:
79 // a function, returning 0.5
81 SystemClock.sched(0.0,
82         { "***".postln; 0.5 }
86 // a stream, returning 0.5 and 0.1
88 SystemClock.sched(0.0,
89         Routine({ loop {
90                 "***".postln; 0.5.yield;
91                 "_*_".postln; 0.1.yield;
92         } });
96 // this is the reason why 'wait' works the same (for numbers) like 'yield'
98 SystemClock.sched(0.0,
99         Routine({ loop {
100                 "***".postln; 0.5.wait;
101                 "_*_".postln; 0.1.wait;
102         } });
107 Streams that return strong::numbers:: can be played directly with the strong::play:: message.
109 code::
110 // play at the next beat, with offset 0.4
112 Routine({ loop {
113         "***".postln; 0.5.wait;
114         "_*_".postln; 0.1.wait;
115 } }).play(quant:[1, 0.4]);
119 Streams that return strong::Events:: need to be wrapped in an link::Classes/EventStreamPlayer::. The Event's strong::delta:: (can also be set by strong::dur::) is used as a scheduling beats value:
121 code::
122 // play at the next beat, with offset 0.4
124 Routine({ loop {
125         "///".postln; (delta:0.5).yield;
126         "_/_".postln; (delta: 0.1).wait;
127 } }).asEventStreamPlayer.play;
131 subsection::Iteration
133 The method link::#-do:: effectively 'plays' a stream by iterating all of its contects.
135 And the following messages create a stream by filtering another stream in some way: link::#-collect::, link::#-reject::, link::#-select::, link::#-dot::, link::#-interlace::, link::#-appendStream::, link::#-embedInStream::, link::#-trace::.
137 subsection::Composite Streams
139 Routines can be strong::embedded:: in each other, using link::#-embedInStream:: :
141 code::
142 // example
144 x = Routine({
145         2.do({
146                 [1,2,3,4].do({ arg i; i.yield; });
147         });
149 y = Routine({
150         100.yield;
151         30.yield;
152         x.embedInStream;
153         440.yield;
154         1910.yield;
156 17.do({ y.next.postln });
160 Routines can be strong::concatenated:: just like Streams:
162 code::
164 x = Routine({
165         2.do({
166                 [1,2,3,4].do({ arg i; i.yield; });
167         });
169 y = Routine({
170         100.yield;
171         30.yield;
173 z = x ++ y;
174 17.do({ z.next.postln });
178 Routines can be strong::combined:: with the composition operator <>
180 code::
182 x = Routine({ arg inval;
183         2.do({
184                 [1,2,3,4].do({ arg i;
185                         if(inval.isNil) { nil.alwaysYield };
186                         inval = (i * inval).yield;
187                 });
188         });
190 y = Routine({
191         100.yield;
192         30.yield;
193         4.do { 1.0.rand.yield };
195 z = x <> y;
196 17.do({ z.value.postln }); // call .value here, as this is a function.
200 Composite Streams can be defined as combinations of Streams using the unary and binary messages.
202 subsection::Unary messages
204 Streams support most of the unary messages defined in link::Classes/AbstractFunction:: :
206 code::
208 a = Routine({ 20.do({ 33.rand.yield }) });
209 b = Routine({ [-100,00,300,400].do({ arg v; v.yield}) });
211 c = b.neg; // define a composite stream
213 // enumerate and perform all of the unary messages:
215         \neg, \reciprocal, \bitNot, \abs, \asFloat, \asInteger, \ceil,
216         \floor, \frac, \sign, \squared, \cubed, \sqrt, \exp, \midicps,
217         \cpsmidi, \midiratio, \ratiomidi, \ampdb, \dbamp, \octcps,
218         \cpsoct, \log, \log2, \log10, \sin, \cos, \tan, \asin, \acos, \atan,
219         \sinh, \cosh, \tanh, \rand, \rand2, \linrand, \bilinrand, \sum3rand,
220         \distort, \softclip, \coin, \even, \odd, \isPositive, \isNegative,
221         \isStrictlyPositive
223 .do({ arg msg;
224         postf("\n msg: % \n", msg);
225         b.reset.perform(msg).do({arg v; v.post; " ".post;});
227 nil;
231 subsection::Binary messages
233 Streams support the following binary messages defined in link::Classes/AbstractFunction:: :
235 code::
237 a = Routine({ 20.do({ 33.rand.yield }) });
238 b = Routine({ [-100,00,300,400].do({ arg v; v.yield}) });
240         '+' , '-' , '*', '/', \div, '%', '**', \min, \max, '<', '<=', '>', '>=', '&', '|',
241         \bitXor, \lcm, \gcd, \round, \trunc, \atan2,
242         \hypot, '>>', '+>>', \ring1, \ring2, \ring3, \ring4,
243         \difsqr, \sumsqr, \sqrdif, \absdif, \amclip,
244         \scaleneg, \clip2, \excess, '<!', \rrand, \exprand
246 .do({ arg msg;
247         postf("\n msg: % \n", msg);
248         b.reset.perform(msg).do({ arg v; v.post; " ".post; });
250 nil;
254 InstanceMethods::
256 method::play
257 Streams that return strong::numbers:: can be played directly with the strong::play:: message. Streams that return strong::events:: need to be wrapped in an link::Classes/EventStreamPlayer::. See link::#-asEventStreamPlayer::.
259 argument::clock
260 a clock. link::Classes/TempoClock:: by default.
262 argument::quant
263 either a number strong::n:: (quantize to strong::n:: beats), or an array strong::[n, m]:: (quantize to n beats, with offset m).
265 method::do
266 iterate until a nil is encountered.
267 warning::
268 Applying do to an endless stream will lock up the interpreter!
271 method::collect
272 iterate indefinitely.
274 method::reject
275 return only those elements for which function.value(element) is false.
277 method::select
278 return only those elements for which function.value(element) is true.
280 method::dot
281 return function.value(this.next, stream.next) for each element.
283 method::interlace
284 iterate all of stream for each element of this. Combine the values using function.
286 method::appendStream
287 append stream after this returns nil. The same like ++
289 method::embedInStream
290 iterate all of this from within whatever Stream definition it is called.
292 method::trace
293 print out the results of a stream while returning the original values.
295 argument::key
296 when streaming events, post only this key.
298 argument::printStream
299 printOn this stream (default: link::Classes/Post::).
301 argument::prefix
302 string added to the printout to separate different streams.