2 ScoreStreamPlayer collects OSC commands from an EventStream into a Score. It is derived from server to provide allocation of nodeIDs, bufums, etc.
4 It implements the functionality of a TempoClock, to support tempo changes and time based patterns.
6 Patterns that play on multiple servers are not directly supported, but can be managed.
7 For example, assuming the server is explicitly identified in the pattern:
9 arrayOfScores = arrayOfServers.collect { | server |
13 if (ev[\server] == server)
23 ScoreStreamPlayer : Server {
25 var <>bundleList, <>maxTime;
27 *new { ^super.new("record").initScoreStreamPlayer }
29 initScoreStreamPlayer {
31 Server.set.remove(this); // we do not want to be part of the server list
35 beats2secs { | beats | ^beats }
36 secs2beats { | beats | ^beats }
39 bundleList = bundleList.add([beats min: maxTime] ++ args)
42 prepareEvent { | event |
45 ~schedBundle = { | lag, offset, server ...bundle |
46 this.add(offset * tempo + lag + beats, bundle)
48 ~schedBundleArray = { | lag, offset, server, bundle |
49 this.add(offset * tempo + lag + beats, bundle)
55 makeScore { | stream, duration = 1, event, timeOffset = 0|
56 var ev, startTime, proto;
60 schedBundle: { | lag, offset, server ...bundle |
61 this.add(offset * tempo + lag + beats, bundle)
63 schedBundleArray: { | lag, offset, server, bundle |
64 this.add(offset * tempo + lag + beats, bundle)
68 event = event ? Event.default;
69 event = event.copy.putAll(proto);
73 maxTime = timeOffset + duration;
75 thisThread.clock = this;
77 thisThread.beats = beats;
78 ev = stream.next(event.copy);
79 (maxTime >= beats) && ev.notNil
83 beats = ev.delta * tempo + beats
86 bundleList = bundleList.sort({ | a, b | b[0] >= a[0] });
87 if ((startTime = bundleList[0][0]) < 0 ) {
88 timeOffset = timeOffset - startTime;
90 // bundleList.do { | b | b[0] = b[0] + timeOffset }
92 ^Score(bundleList.add([duration+timeOffset, [\c_set, 0, 0]]) );