SCDoc: Use proper static string constants instead of comparing string literals.
[supercollider.git] / SCClassLibrary / Common / Streams / PmonoStreams.sc
blob74b3e73c9876e982b0ef929e43f146cb30df1578
1 // these are internal classes, used by Pmono and PmonoArtic
2 // they're not likely to work well if you try to use them outside that context
4 PmonoStream : Stream {
5         var     pattern,
6                 id, server, cleanup, currentCleanupFunc,
7                 event,
8                 streamout, name,
9                 streampairs, endval,
10                 msgFunc, hasGate, synthLib, desc, schedBundleArray, schedBundle;
12         *new { |pattern|
13                 ^super.newCopyArgs(pattern)
14         }
16         embedInStream { |inevent|
17                 inevent ?? { ^nil.yield };
19                 this.prInit(inevent);
21                 loop {
22                         if(this.prDoStreams) {
23                                 // always on the first iteration; should not happen thereafter
24                                 if(id.isNil) { this.prInitNode };
25                                 cleanup.update(event);
26                                 inevent = event.yield;
27                                 this.prSetNextEvent(inevent);
28                         } {
29                                 ^cleanup.exit(inevent)
30                         }
31                 }
32         }
34                 // private methods abstracted out for the benefit of subclasses
35                 // you should not use these directly
36         prInit { |inevent|
37                 cleanup = EventStreamCleanup.new;
38                 streampairs = pattern.patternpairs.copy;
39                 endval = pattern.patternpairs.size - 1;
40                 forBy (1, endval, 2) { | i | streampairs[i] = streampairs[i].asStream };
42                 event = inevent.copy;
43                 event.use {
44                         synthLib = ~synthLib ?? { SynthDescLib.global };
45                         ~synthDesc = desc = synthLib.match(pattern.synthName);
46                         if (desc.notNil) {
47                                 ~hasGate = hasGate = desc.hasGate;
48                                 ~msgFunc = desc.msgFunc;
49                         }{
50                                 ~msgFunc = ~defaultMsgFunc;
51                                 ~hasGate = hasGate = false;
52                         };
53                         msgFunc = ~msgFunc;
54                 }
55         }
57         prInitNode {
58                 event.use {
59                         if (~id.notNil) {
60                                 ~type = \monoSet;
61                                 id = ~id;
62                         } {
63                                 ~type = \monoNote;
64                                 ~instrument = pattern.synthName;
65                                 cleanup.addFunction(event, currentCleanupFunc = { | flag |
66                                         if (flag) { (id: id, server: server, type: \off,
67                                                 hasGate: hasGate,
68                                                 schedBundleArray: schedBundleArray,
69                                                 schedBundle: schedBundle).play
70                                         }
71                                 });
72                         };
73                         // this should happen whether or not ~id is nil
74                         ~updatePmono = { | argID, argServer |
75                                 id = argID;
76                                 server = argServer;
77                                 schedBundleArray = ~schedBundleArray;
78                                 schedBundle = ~schedBundle;
79                         };
80                 };
81         }
83         prDoStreams {
84                 forBy (0, endval, 2) { | i |
85                         name = streampairs[i];
86                         streamout = streampairs[i+1].next(event);
87                         streamout ?? { ^false };
88                         if (name.isSequenceableCollection) {
89                                 name.do { | n, i | event[n] = streamout[i] };
90                         }{
91                                 event[name] = streamout;
92                         };
93                 };
94                 ^true
95         }
97         prSetNextEvent { |inevent|
98                 event = inevent.copy;
99                 event.use{
100                         ~server = server;
101                         ~id = id;
102                         ~type = \monoSet;
103                         ~msgFunc= msgFunc;
104                 };
105         }
108 PmonoArticStream : PmonoStream {
109         embedInStream { |inevent|
110                 var     sustain, rearticulating = false;
111                 inevent ?? { ^nil.yield };
113                 this.prInit(inevent)
114                         .prInitNode;
116                 loop {
117                         if(this.prDoStreams) {
118                                 sustain = event.use { ~sustain.value };
119                                 if(sustain.notNil and: { sustain < event.delta }) {
120                                         event[\removeFromCleanup] = event[\removeFromCleanup].add(currentCleanupFunc);
121                                         thisThread.clock.sched(sustain, {
122                                                 currentCleanupFunc.value(true);
123                                                 rearticulating = true;
124                                         });
125                                 } { rearticulating = false };
126                                 cleanup.update(event);
127                                 inevent = event.yield;
128                                 this.prSetNextEvent(inevent);
129                                 if(rearticulating) {
130                                         event[\id] = nil;
131                                         this.prInitNode;
132                                 };
133                         } {
134                                 ^cleanup.exit(inevent)
135                         }
136                 }
137         }