(define clock-server-receive
(lambda (timestamp address srcip srcport . args)
(cond ((string=? address "/clock/bpm/set")
(apply io:osc:send (now) *toplap-sync-server* "/clock/bpm/set" args))
((string=? address "/clock/bpm/update") ;; bpm/update may come from SYNC!
;; pass update to client
(apply io:osc:send (now) *toplap-clock-client* "/clock/bpm/update" args)
;; and also apply locally in case client is not extempore!
(let ((time (join-clock-time (car args) (cadr args)))
(beat-n (caddr args))
(beat-d (cadddr args))
(bpm (car (cddddr args))))
(if (and (not *master*) (<> bpm *clock-oldbpm*))
(begin
(set! *clock-oldbpm* bpm)
(*metro* 'set-tempo bpm (clock->samples time) (/ beat-n beat-d))))))
((string=? address "/clock/cycle/set")
(apply io:osc:send (now) *toplap-sync-server* "/clock/cycle/set" args))
((string=? address "/clock/cycle/update") ;; cycle/update may come from SYNC!
;; pass update onto client
(apply io:osc:send (now) *toplap-clock-client* "/clock/cycle/update" args)
;; and also apply locally in case client is not extempore!
(let ((beat-n (car args))
(beat-d (cadr args))
(cycle (caddr args)))
(if (and (not *master*) (<> cycle *clock-oldcycle*))
(begin
(set! *clock-oldcycle* cycle)
(*metro* 'set-cycle cycle (/ beat-n beat-d))))))
((string=? address "/clock/offset/q")
;; retrieve clock offset
(let ((offset (split-clock-time *toplap-clock-global-offset*)))
(io:osc:send (now) (cons srcip srcport) "/clock/offset/r"
(car offset) (cdr offset))))
((string=? address "/clock/state/q")
(let* ((bpmmark (*metro* 'get-mark))
(bpmtime (split-clock-time (car mark)))
(bpm-beat (cdr mark))
(bpm (*metro* 'get-tempo))
(cycle (*metro* 'get-cycle))
(cycle-beat (*metro* 'get-cycle-mark)))
;; retieve state of the world!
(io:osc:send (now) *toplap-clock-client* "/clock/state/r"
(car bpmtime) (cdr bpmtime)
(rational->n bpm-beat) (rational->d bpm-beat)
bpm
(rational->n cycle-beat) (rational->d cycle-beat)
cycle)))
(else (println 'bad 'osc 'message: address))))))