Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / SCClassLibrary / Common / Streams / NodeEvents.sc
blob51e2d980885409a9219d4be2cb33894984465a89
1 /*
2 This file defines Group and Synth event types similar to the Group and Synth classes.
3 They follow the conventions of patterns, using integers (0,1,2,3) for addActions and
4 integer nodeID's as targets.
6 For example,
8         g = (type: \Group, id: 2);
9         g.play;
10         a = (type: \Synth, group: 2)
11         a.play;
13 Would start a group with nodeID = 2 and play a synth within that group.  If the event id is left unspecified, it is automatically allocated when the event is played.
15 Caution, Event-play returns a time value, so an expression of the form
17         a = (type: \Group, id: 1).play
19 will assign the default duration of 1 to the variable a, not the group event!
21 The interface to these events is a hybrid of the Pattern and Node control interfaces consisting of
22         play, stop, pause, resume
23         release, set, map, before, after, headOf, tailOf
25 event[\id] can be an array. In this case, a set of nodes corresponding to each element of the array will be created and the order of the id's will be the order of the nodes running on the server.  (In other word, the nodes are created in reverse order when event[\addAction] is 0 or 2.
27 With the exception of ~server, ~latency, and ~instrument any key in the event can have an array as a value and the standard rules of multi-channel expansion will be followed.
29 These event types can be used in patterns, but are probably more useful for more static use
30 in system configuration or to control individual synths.
32 Here is a simple example of its use:
34         g = (type: \Group, id: [2,3,4,5,6], group: 0, addAction: 1);  // define a multiple Group event
35         g.play;                                                                                   // play it
36         h = g.split;                                                 // split it into individual groups
38         b = (type:\Synth, freq: [500,510], group: [2,3]);           // make a Synth event
39         b.play;
40         c = b.split;
42         b.set(\freq,[1000,1200])
44         c[0].set(\freq,700);
45         c[1].set(\freq,400);
47         h[0].release;
48         h[1].release;
50         g.stop;
54 +Event {
55         *checkIDs { | id, server |
56                 if (id.isNil) {^nil};
57                 if (id.asArray.first < (if(server.notNil) { server.options.initialNodeID } { 1000 })) { ^id};
58                 ^nil
59         }
61         asEventStreamPlayer {}
63         sendOSC { | msg |
64                 if (this[\isPlaying]) {
65                         this[\server].sendBundle(this[\latency],  *(msg.flop) )
66                 }
67         }
68         set { | ... args |
69 //              this.sendOSC([15, this[\id]] ++ (args.asOSCArgArray));
70                 args = ([15, this[\id]] ++ args).flop.asOSCArgBundle;
71                 if (this[\isPlaying]) {
72                         this[\server].sendBundle( this[\latency],  *args )
73                 }
74         }
76         stop { this.use { ~stopServerNode.value }  }
77         pause { this.use { ~pauseServerNode.value }  }
78         resume { this.use { ~resumeServerNode.value }  }
79         release { |releaseTime| this.use { ~releaseServerNode.value(releaseTime) }  }
80         free { this.use { ~freeServerNode.value }  }
82         synth {
83                 this.parent = Event.parentEvents[\synthEvent];
84         }
85         group {
86                 this.parent = Event.parentEvents[\groupEvent];
87         }
89         split { | key = \id |
90                 var event;
91                 if (this[\isPlaying] == true) {
92                         ^this[key].asArray.collect { |keyVal|
93                                 event = this.copy.put(key, keyVal);
94                                 NodeWatcher.register(event);
95                                 event;
96                         }
97                 } {
98                         ^this[key].asArray.collect { |keyVal|
99                                 this.copy.put(key, keyVal)
100                         }
101                 }
102         }
103         nodeID { ^(this[\id].asArray[0]) }
105         asGroup {
106                 var type = this[\type];
107                 if(type == \Group) { ^this };
108                 ^this[\group].asGroup
109         }