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           <--