[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Pattern records
- To: bill@cambridge.apple.com
- Subject: Re: Pattern records
- From: "Mark A. Tapia" <markt@dgp.toronto.edu>
- Date: Sat, 10 Oct 1992 18:29:58 -0400
- Cc: info-mcl@cambridge.apple.com
howell@cats.UCSC.EDU writes:
> The following code should produce lists of zeros pushed into
> "test" and it does not. Can anyone tell me why not? Is there
> a problem with "get-internal-real-time?" This is causing a
> nightmare in a real-time playback system, a problem which has
> not, I think, existed (at least to this degree) in previous
> versions of Mac COMMON LISPSs.
> (setq test ())
> (play 60 1000 (get-internal-real-time))
> (defun play (MM counter start-time)
> (cond ((equal counter 0)())
((<= start-time (get-internal-real-time))
(progn
(push (- start-time (get-internal-real-time)) test)
;(play-note 60)
(play MM (1- counter)(+ start-time MM))))
(t (play MM counter start-time))))
#|
(0 0 0 -13 0 0 0 0 0 0 -11 0 0 0 0 0 0 -7 0 0 0 0 0 0 0 -14 0 0 0 0 0 0 0 0 0 0
0 0 0 0)
3 > test
(0 0 0 -26 0 0 0 -13 0 0 0 0 0 0 -3 0 0 0 0 0 0 0)
|#
Answer:
You're seeing the result of an increased time resolution from
60 ticks per second to 1000 ticks per second (internal-time-units-per-second).
The gaps are on the order of between .003 seconds and .026 seconds
(between 0 seconds and 2/60 second). All gaps up to 17 would not be noticed
before.
Conversion 1 old tick = 50/3 new ticks (or less than 17 new ticks).
Choosing times that are a multiple of 1ms will be much better.
The clock is more likely to advance a tick between the first call to
get-internal-real-time and the second.
If your intention is to "wait" until a certain amount of time (in seconds)
have elapsed, it would be better to code a specific wait function.
Using the wait function and running without interrupts eliminates
additional ticks.
Results of running the modified version of the play function
with a generalized wait function
time ticks missing
with interrupts 1.930 620
without 1.617 0
(defparameter test nil)
(defun wait-ticks (current-time &optional (n 1/60))
"wait until the internal time is current-time + n seconds
return the new time and either nil or the excess number of ticks"
(declare (optimize (speed 3) (safety 0)))
(let* ((end-time (+ (truncate (* n internal-time-units-per-second))
current-time))
(next-time (get-internal-real-time))
(wait-time (- end-time next-time)))
(when (> wait-time 0)
(loop until (>= next-time end-time)
do (setq next-time (get-internal-real-time))))
(values next-time
(when (> next-time end-time)
(- next-time end-time)))))
(defun play (MM counter start-time &key (wait-time 1/60))
(loop until (<= counter 0)
with gap and time = start-time and gaps = 0
do (progn (push (- time (get-internal-real-time)) test)
;(play-note 60)
(multiple-value-setq (time gap)
(wait-ticks time wait-time))
(when gap (incf gaps gap))
(decf counter))
finally (return gaps)))
? (progn
(gc)
(setq test nil)
(time (play 60 100 (get-internal-real-time))))
(PLAY 60 100 (GET-INTERNAL-REAL-TIME)) took 1930 milliseconds
(1.930 seconds) to run.
4056 bytes of memory allocated.
282
? (progn
(gc)
(setq test nil)
(time (without-interrupts (play 60 100 (get-internal-real-time)))))
(WITHOUT-INTERRUPTS (PLAY 60 100 (GET-INTERNAL-REAL-TIME))) took 1617 milliseconds
(1.617 seconds) to run.
4056 bytes of memory allocated.
0
0