Hi Julian, On the contrary, the ESP is the only thing that actually knows when all events have been computed for a particular time position in the EventStream. Er, a little more precisely the root EventStream is the only thing to know and it tells the EventStreamPlayer. Here is some untested code (with some pseudo-code) to illustrate the approach I am advocating: +EventStreamPlayer { register { Event.bundleDictionaries.put(thisThread, () ) } unregister { Event.bundleDictionarys.put(thisThread, nil) } play { this.register; super.play } // pseudo-code stop { super.stop; this unregister } //pseudo-code } +Event { classvar <bundleDictionaries = (); // pseud-ocode bufferedOSC { // set up the necessary keys in the Event this[\bundles] = EventStreamPlayer.bundleDictionaries[thisThread]; this[\schedBundle] = #{ |lag, offset, server ...bundle | thisThread.clock.sched ( offset, { if (lag !=0 ) { SystemClock.sched( lag, { server.sendBundle(server.latency, *bundle) }) } { ~bundles[server] = ~bundles[server] ++ bundle } }) }; this[\schedBundleArray] = #{ | lag, offset, server, bundleArray | thisThread.clock.sched ( offset, { if (lag !=0 ) { SystemClock.sched(lag, { server.sendBundle(server.latency, *bundleArray) }) } { ~bundles[server] = ~bundles[server] ++ bundle } }) }; } playAndDelta { | cleanup, mute | var delta, bundlesDict; if (mute) { this.put(\freq, \rest) }; this. bufferedOSC; cleanup.update(this); this.play; delta = this.delta; if (delta != 0) { bundlesDict = EventStreamPlayer.bundleDictionaries[thisThread]; bundlesDict.keys.do { | s | s.sendBundle(s.latency, *bundlesDic[s]) }; bundlesDict.clear; }; ^delta } } |