3/1/97 12:00 AM
Subject: MAX Digest - 27 Feb 1997 to 28 Feb
1997To: Recipients of MAX digests 

There are 2 messages totalling 114 lines in this issue.

Topics of the day:

  1. PB 5300
  2. stack overflows


Date:    Fri, 28 Feb 1997 10:33:38 EST
From:    Tom Ritchford 
Subject: Re: PB 5300

"Joseph W. Rovan" <105561.3371@COMPUSERVE.COM> wrote:
>Tom Bellman writes:....
>I've had good luck running Max on my 5300 (I've been using SpeedDoubler).
>But today the famous "snapping-sound-of-case-breaking" feature finally
>struck, and the screen is soon to be removable....

Not really on topic for the Max list, but Apple is very good about
fixing this problem.  I had a bad hinge on my 190cs and then I
dropped it on the floor(!), preventing it from being rechargeable.
Calling 800-SOS-APPL got a box delivered in two days, shipped it off,
had it back in less than two weeks.  No charge, even though I admitted
my sin -- apparently the recharger problem is also a manufacturing

I beleive that the 190 and 5300 use basically the same case and power
supply so you should be in the same case.  You only have another 5 years
or so left to take advantage of the free fix, though!


Tom Ritchford              

    Verge's "Little Idiot" -- Music for the mentally peculiar.


Date:    Fri, 28 Feb 1997 11:43:18 -0800
From:    Peter Elsea 
Subject: stack overflows

Some discussion about this old problem lately:

First Amanda Pehlke asks:
>I wonder if someone would be good enough to help me figure out why I get
>stack overflows if I put more than about 40 Lmatches to work at once.  I
>hoping for 62.  Quadra 650, heaps o' RAM.

I don't have the source code handy right now, but many of the Lobjects
create a temprary array to hold a working copy of the list being processed-
with the increase of maximum list size to 256 members, this means that
Lmatch and some others will gobble 1.5k (a list member takes 6 bytes) of
stack space. Even so, there ought to be enough stack to handle this because
the objects take turns (only David Z knows how much stack there really is).
(Note to externals programmers- if you create local arrays like this, make
sure the array goes out of scope before you do any output. Otherwise the
array will stay on the stack until all consequences are resolved. Come to
think of it, I better go back and check my own code!)

In any case, there is no reason to have 62 or even 40 copies of Lmatch.
Amanda's patch is an extension of the principles I described here are few
weeks ago and illustrated with a simple chord identifier. Amanda has
expanded that beyond my wildest dreams, and I am gratified that the
principles do hold up when taken to the limits. In my example, I used a
seperate Lmatch for each case in order to clearly show what was going on.
(The unknown chord is converted into a pitch set, then stored in Lmatch. A
template set is then applied to Lmatch and Lmatch will report if the
template is found within the unknown). In a larger implementation, you can
store the templates in a coll and feed them to Lmatch one at a time- if
Lmatch reports success, the index of the coll is the key to the chord type,
if failure, Lmatch sends a next request back to the coll. Careful here!
The coll must end with something guaranteed to succeed, such as a simple 1.
Otherwise an unlisted chord *will* cause a stack overflow.

Roland Hemming asks:
>Lets say we have an object with 2 outlets and ints come out of each
>outlet. The
>right hand outlet int goes via another object back to the left inlet of out
>origonal object. If we were to 'trace' this operation we would see that by
>time the right outlet int had reached the object's inlet again we hadn't
>output the first int out of the left outlet. I can guess that we might get
>a stack overflow then.

Sure do. One of the mysteries of Max is that everything connected to right
outlets happens all the way to the bottom of the patch before any left
outlet gets a shot. (Then execution backs up the tree, exploring left
outlets from the bottom up. ) while this is going on, the triggering
messages are held on the stack. They aren't released until all consequences
of all stacked message are resolved. If a right outlet somehow triggers
output from the right outlet .....

The solution to this kind of problem is the defer object. Defer is
undocumented in older versions of Max (not even a help file). All defer
does is hold on to its input until all activity ceases, then sends the data
along. This is more effective than delays because defer always works and
doesn't slow down your patch.

Some old timers will argue that you shouldn't loop this way in Max- if you
want something to happen a hundred times you should use [uzi 100]. There's
an interesting theoretical discusion here, but the real reason is what with
the right priority, bottom up execution of left branches, and Max's habit
of occasionally changing its mind as to which is the right branch, loops
are notoriously wobbly. It's just too hard to get an iron clad termination

Of course, pragmatist (and unrepenitant C coder) that I am, there's an
Lobject called Loop. It includes defer, keeps a loop index, and terminates
after the proper number of iterations.

Peter Elsea
Electronic Music Studios
University of California, Santa Cruz


End of MAX Digest - 27 Feb 1997 to 28 Feb 1997