File: Pproto.sc

package info (click to toggle)
supercollider 1%3A3.10.0%2Brepack-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 45,496 kB
  • sloc: cpp: 283,513; lisp: 74,040; ansic: 72,252; sh: 23,016; python: 7,175; makefile: 1,087; perl: 766; java: 677; yacc: 314; lex: 175; ruby: 136; objc: 65; xml: 15
file content (98 lines) | stat: -rw-r--r-- 2,496 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
Pfpar : ListPattern {
	initStreams { arg priorityQ;
		list.do({ arg pattern, i;
			priorityQ.put(0.0, pattern.asStream);
		});
	}

	embedInStream { arg inval;
		var assn;
		var priorityQ = PriorityQueue.new;
		var cleanup = EventStreamCleanup.new;

		repeats.value(inval).do({ arg j;
			var outval, stream, nexttime, now = 0.0;

			this.initStreams(priorityQ);

			// if first event not at time zero
			if (priorityQ.notEmpty and: { (nexttime = priorityQ.topPriority) > 0.0 }, {
				inval = Event.silent(nexttime, inval).yield;
				now = nexttime;
			});

			while({
				priorityQ.notEmpty
			},{
				stream = priorityQ.pop;
				outval = stream.next(inval).asEvent;
				if (outval.isNil, {
					priorityQ.clear;
					^cleanup.exit(inval);
				},{
					cleanup.update(outval);
					// requeue stream
					priorityQ.put(now + outval.delta, stream);
					nexttime = priorityQ.topPriority;
					outval.put(\delta, nexttime - now);

					inval = outval.yield;
					// inval ?? { this.purgeQueue(priorityQ); ^nil.yield };
					now = nexttime;
				});
			});
		});
		^inval;
	}
}

Pproto  : Pattern {

	var <>makeFunction, <>pattern, <>cleanupFunc;

	*new { | makeFunction, pattern, cleanupFunc|
		^super.newCopyArgs( makeFunction, pattern, cleanupFunc)
	}
	storeArgs { ^[makeFunction,pattern,cleanupFunc] }
	embedInStream { | event |
		var stream,  ev, evType;
		var cleanup, cleanupList, eventCleanupFunc;
		var proto;							// temporary proto event used in allocation
		var makeRoutine;						// routine wrapper for function that makes protoEvent
		var protoEvent;						// protoEvent created by function

// Step 1: generate resources from function
		proto = (
			delta: 0, 						// events occur simultaneously
			finish: { ev = currentEnvironment} 	// get copy of event object actually played
		);
		protoEvent = ();
		makeRoutine = Routine({ protoEvent.make (makeFunction) });

		while {
			(ev = makeRoutine.next(ev)).notNil;
		} {
			event = ev.proto_(proto).yield;
			ev.proto = nil;
			cleanupList = cleanupList.add(ev)
		};

		cleanup = EventStreamCleanup.new;
		eventCleanupFunc = { | flag |
			cleanupList.do { | ev |
				EventTypesWithCleanup.cleanup(ev, flag)
			}
		};
		cleanupFunc = eventCleanupFunc ?? { { | flag | eventCleanupFunc.value(proto, flag) } };
		cleanup.addFunction(event, cleanupFunc);

		stream = Pfpar(pattern.asArray).asStream;
		loop {
			ev = event.copy.putAll(protoEvent);
			ev = stream.next(ev) ?? { ^cleanup.exit(event) };
			event = ev.yield;
		};
		^event
	}

}