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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
OSCBundle {
var <messages, <preparationMessages;
add { arg msg; messages = messages.add(msg) }
addAll { arg mgs; messages = messages.addAll(mgs) }
addPrepare { arg msg; preparationMessages = preparationMessages.add(msg) }
// the sound starts at: (next beat + latency) when the preparation is finished
// the client side task starts at: preparationTime + next beat
// next beat is 0 if no clock is passed in.
// eventstreams e.g. take into account the latency internally
schedSend { arg server, clock, quant;
server = server ?? { Server.default };
this.doPrepare(server, {
if(quant.isNil or: { clock.isNil }) {
this.prSend(server, server.latency)
} {
clock.schedAbs(quant.nextTimeOnGrid(clock), {
this.prSend(server, server.latency);
});
};
});
}
send { arg server, time, timeOfRequest;
server = server ?? { Server.default };
timeOfRequest = timeOfRequest ?? {Main.elapsedTime};
this.doPrepare(server, { this.prSend(server, time,timeOfRequest) })
}
// see atTime helpfile
sendAtTime { arg server, atTime, timeOfRequest; // offset by preparation
server = server ?? { Server.default };
atTime.schedBundle(this,server,timeOfRequest ?? { Main.elapsedTime});
}
doPrepare { arg server, onComplete;
if(preparationMessages.isNil) { ^onComplete.value };
Routine.run {
server.sync(Condition.new, preparationMessages);
onComplete.value;
};
}
// private //
prSend { arg server, delta,timeOfRequest;
if(messages.notNil, {
server.listSendBundle(delta ?? { server.latency }, messages);
})
}
}
MixedBundle : OSCBundle {
var <sendFunctions; // functions to evaluate on send
var <functions; // functions to evaluate when the bundle is scheduled on the server
onSend { arg func;
sendFunctions = sendFunctions.add(func);
}
addFunction { arg func;
functions = functions.add(func);
}
sched { arg time=0.0, func;
sendFunctions = sendFunctions.add({ SystemClock.sched(time, { func.value; nil }) });
}
addMessage { arg receiver, selector, args;
functions = functions.add( Message(receiver,selector,args) )
}
addOnSendMessage { arg receiver, selector, args;
sendFunctions = sendFunctions.add( Message(receiver,selector,args) )
}
doFunctions {
functions.do({ arg item; item.value });
}
doSendFunctions {
sendFunctions.do({ arg item; item.value });
}
// private //
prSend { arg server, delta, timeOfRequest;
if(delta.isNil,{
delta = server.latency;
},{
if(timeOfRequest.notNil,{
delta = (timeOfRequest + delta) - Main.elapsedTime;
if(delta.isNegative,{
("bundle sent late:" + delta).warn;
delta = 0.0;// just send it now
});
});
});
if(functions.notNil) {
SystemClock.sched(delta ? 0.0, {
this.doFunctions;
});
};
if(messages.notNil) {
server.listSendBundle(delta, messages);
};
this.doSendFunctions;
}
}
|