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
6 id, server, cleanup, currentCleanupFunc,
10 msgFunc, hasGate, synthLib, desc, schedBundleArray, schedBundle;
13 ^super.newCopyArgs(pattern)
16 embedInStream { |inevent|
17 inevent ?? { ^nil.yield };
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);
29 ^cleanup.exit(inevent)
34 // private methods abstracted out for the benefit of subclasses
35 // you should not use these directly
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 };
44 synthLib = ~synthLib ?? { SynthDescLib.global };
45 ~synthDesc = desc = synthLib.match(pattern.synthName);
47 ~hasGate = hasGate = desc.hasGate;
48 ~msgFunc = desc.msgFunc;
50 ~msgFunc = ~defaultMsgFunc;
51 ~hasGate = hasGate = false;
64 ~instrument = pattern.synthName;
65 cleanup.addFunction(event, currentCleanupFunc = { | flag |
66 if (flag) { (id: id, server: server, type: \off,
68 schedBundleArray: schedBundleArray,
69 schedBundle: schedBundle).play
73 // this should happen whether or not ~id is nil
74 ~updatePmono = { | argID, argServer |
77 schedBundleArray = ~schedBundleArray;
78 schedBundle = ~schedBundle;
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] };
91 event[name] = streamout;
97 prSetNextEvent { |inevent|
108 PmonoArticStream : PmonoStream {
109 embedInStream { |inevent|
110 var sustain, rearticulating = false;
111 inevent ?? { ^nil.yield };
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;
125 } { rearticulating = false };
126 cleanup.update(event);
127 inevent = event.yield;
128 this.prSetNextEvent(inevent);
134 ^cleanup.exit(inevent)