zmq randomly disconnects sockets added by krgn on Mon Aug 19 22:06:24 2013
(define (process-ipc-messages socket pattern) (let loop ((msg "")) ;; parse json from zmq message body and update the respective track (let ((track (with-input-from-string msg read-json))) (if track (update-track track pattern))) (loop (receive-message* socket)))) (define (main) (let* ((current-bpm 120) (current-step 0) (sixteenth-note (sixteenth-by-bpm current-bpm)) (pattern (make-default-pattern)) (clock-socket (make-socket 'push (make-context 4))) (song-update-socket (make-socket 'pull (make-context 4))) (ipc-thread (make-thread (lambda () (process-ipc-messages song-update-socket pattern))))) ;; ------------------------------------------------------------ ;; ;; initialize the zmq sockets (bind-socket clock-socket "tcp://127.0.0.1:8888") (connect-socket song-update-socket "tcp://127.0.0.1:8889") ;; ------------------------------------------------------------ ;; ;; start the thread containing our loop to block for and process ;; incoming messages from node.js (thread-start! ipc-thread) ;; ------------------------------------------------------------ ;; ;; enter the main sequencer loop (let main-loop ((counter 0)) ;counter is always in milliseconds (begin ;; every time we're on an exact sixteenth step we increment or reset our current-step (if (zero? (modulo counter (sixteenth-by-bpm current-bpm))) (begin (if (not (= counter (bar-in-ms current-bpm))) (set! current-step (inexact->exact (/ counter sixteenth-note)))) (send-message clock-socket (number->string current-step)))) ;; we exectute this function for each track in in pattern (for-each (lambda (track) (let ((latency (alist-ref 'latency (cdr track))) (steps (alist-ref 'steps (cdr track)))) ;; if the current step in the current track is non-zero we see if we have to trigger something (unless (zero? (vector-ref steps current-step)) ;; the 0-latency case first (cond [(and (zero? latency) (zero? (modulo counter (sixteenth-by-bpm current-bpm)))) (print "name: " (alist-ref 'name (cdr track)) " no latency")] [(and (not (zero? latency)) (= latency (modulo counter (sixteenth-by-bpm current-bpm)))) (print "name: " (alist-ref 'name (cdr track)) " latency ticks: " latency)])))) pattern) (thread-sleep! 0.001)) ;sleep for one millisecond (let ((bar-len-ms (bar-in-ms current-bpm))) (cond [(>= counter bar-len-ms) (main-loop 0)] [(< counter bar-len-ms) (main-loop (+ counter 1) )]))))) (main) ;; ---------------------------------------------------------------- ;; Warning (#<thread: thread4>): in thread: (receive-message) Socket operation on non-socket: 88 Call history: seq-ipc.scm:31: loop seq-ipc.scm:29: with-input-from-string seq-ipc.scm:30: update-track seq-ipc.scm:19: alist-ref seq-ipc.scm:20: alist-ref seq-ipc.scm:21: alist-ref seq-ipc.scm:21: alist-update! seq-ipc.scm:31: zmq#receive-message* <-- Error: (send-message) Socket operation on non-socket: 88 Call history: main.scm:40: alist-ref main.scm:41: alist-ref main.scm:39: g224 main.scm:40: alist-ref main.scm:41: alist-ref main.scm:53: thread-sleep! main.scm:54: midi#bar-in-ms main.scm:56: main-loop main.scm:32: midi#sixteenth-by-bpm main.scm:32: modulo main.scm:34: midi#bar-in-ms main.scm:36: number->string main.scm:36: zmq#send-message <--