[CM] process sync...

Rick Taube taube@uiuc.edu
Sat, 7 Jan 2006 10:29:01 -0600


Hi

> Well, this basically works :), but I was hoping that in the case of 
> equal time offsets of the two processes the amp-process would be 
> processed always _first_, because of its first position in the list.

the scheduling queue is sorted by time, if two processes always have 
the same timelines then they should always be processed in the order in 
which they originally entered the queue:

(events (list (process repeat 5 do (format t "~%A: ~s" (now)) wait .1)
               (process repeat 5 do (format t "~%B: ~s" (now)) wait .1))
         nil)
A: 0
B: 0
A: 0.1
B: 0.1
A: 0.2
B: 0.2
A: 0.3
B: 0.3
A: 0.4
B: 0.4
NIL

if processes do not have identical timelines then of course they will 
be processed "out of order" with respect to their original positions in 
the queue once their timelines start to differ, but notice that when 
the timelines happen to line up then A is "before" B:

(events (list (process repeat 5 do (format t "~%A: ~s" (now)) wait .2)
               (process repeat 5 do (format t "~%B: ~s" (now)) wait .1))
         nil)
A: 0
B: 0
B: 0.1
A: 0.2
B: 0.2
B: 0.3
A: 0.4
B: 0.4
A: 0.6
A: 0.8
NIL

> Well, this does not always seem to be the case and I should have 
> checked before, I know, but now I am just wondering how to go about a 
> problem like this and I suppose there must be another approach, or 
> maybe still a way to ensure a fixed order of invocations of the 
> WRITE-EVENT method for equal object times???

it should work like this, you will have to send me a (simple) example 
of it not working for me to see if there is a bug or not.

> I hope these explanations make sense and my intention is understood, 
> I'd be very curious to have a hint how other people go about this (and 
> I suppose this must be quite a common procedure...)

You do not need global variables to share state beween processes. this 
example creates a lexical environment for two processes to share; 
notice that its also possible for a fucntion to return a list of 
processes: in this example the first process sets and uses the lexical 
variables and the second one uses them:

(defun master-and-slave (reps)
   (let (amp key stop) ; look Ma, no globals!
     (list
      ;; master process
      (process repeat reps
                    for k = (between 20 90)
                    for a = (between .3 .8)
                    do (setq amp a key (+ k 12))
                    output (new midi :time (now) :keynum k
                           :duration 1 :amplitude a)
               wait 1
               finally (setq stop t))
      ;; slave
      (process with pat = (new random
                            :of (list (new line :of 1/6 :for 6)
                                      (new line :of 1/5 :for 5)
                                      (new line :of 1/4 :for 4)
                                      (new line :of 1/3 :for 3)
                                      (new line :of 1/2 :for 2)))
               until stop
               for r = (next pat)
               for k = (between key (+ key 12))
               output (new midi :time (now) :keynum k
                           :duration r :amplitude (/ amp 2))
               wait r))))


(cd)
(events (master-and-slave 20) "test.mid")