Re: Multiple calls to draw-line
On Jul 23, 2009, at 1:14 AM, Christopher Melen wrote:
>
> I have a display-callback that draws a grayscale sonogram from fft
> data. To do
> this I'm making a lot of calls to draw-line, since (obviously) I
> need to draw
> each line, representing a frequency bin, with a different grayscale
> value
> (hence I can't use draw-lines or draw-polygon). This seems to slow
> the code up
> considerably. Here is the core loop within the function:
>
> (let ((fft/2 (/ *fft-size* 2))
> (bin-width (round (/ %scroll-height% (/ *sample-rate* *fft-
> size*))))
> (delta (round (/ %scroll-width% *n-frames*))))
> (loop for k of-type fixnum being the hash-key of *spectrum*
> for fr of-type (simple-array double-float (*)) = (gethash k
> *spectrum*)
> for time of-type fixnum = (* delta k)
> do
> (loop for i of-type fixnum from 0 below fft/2
> for freq = (the fixnum (rescale (* i bin-width)
> (* bin-width fft/2)
> %scroll-height%))
> for mag = (the double-float (aref fr (- fft/2 1 i)))
> when (>= mag *cut-off*)
> do
> (gp:draw-line pixmap
> time freq (+ time delta) freq
> :thickness bin-width
> :foreground (make-gray (rescale (float mag 0.0s0)
> *cut-off*
> 1))))))
>
> I have of course profiled, and whilst draw-line didn't seem to be on
> top of the
> stack a lot I still feel it's the culprit. I can't see a way to
> optimize this
> any more, so is there a different way I could do this, without
> having to make
> so many calls to draw-line?
>
> Help/suggestions greatly appreciated,
> Chris
>
I don't know if it's possible with the API you use, but with X or
other drawing systems, we could speed this up by filling a polyline
with a pattern (pixmap) having the wanted grayscale shades.
Or even easier, using that grayscale shade as a background and fill
the complement polyline in black.
In either case, things could be cached in the window server and only
one polyline drawing instruction would have to be issued.
--
__Pascal Bourguignon__
http://www.informatimago.com