Errors in "Step By Step" Book with Pong? Did this object change in Max 8?
Hello, I'm a recent SuperCollider -> Max convert, and I'm currently learning Max 7 through Max for Live. I recently picked up Gregory Taylor's book "Step by Step" as a next step after going through all the tutorials -- I hadn't used Max since Max 5 back in College!
The book has a lot of excellent ideas and great information, but I am continually frustrated by what seem like errors or typos in the book -- some objects in the example patches included with the book's zip file seem to have have some objects hooked up incorrectly (like the "routepass tempo" in the "clock_me" abstraction on p. 28, which has nothing connected to the first, "matching" outlet so "tempo" messages never go anywhere, etc). Since I'm a Max/MSP beginner, I'm hesitant to believe that these things are the expert author's oversights, especially since the book seems to have had an extensive editorial process, but it's maddening to spend 30 minutes trying to understand why something doesn't work or make sense in the included maxpat file and then realizing that it's a mistake in the original file, to the point where I'm considering returning the book.
I have some problems with p. 63-64, and I'm wondering if they have to do with the fact that I'm using Max 7 rather than Max 8, since they appear to not work as described at all.
On p.63, the author writes "Since the pong object expects to receive an integer to set its behavior - mode 0 for wraps and mode 1 for folds - we need to add a little logic to work with a UI object. We can use a umenu, or a live.tab or a textbutton."
The pong objects in the sequencer, are initialized by a patcherargs method sending a "mode 0" message, which actually causes pong objects to NOT to any range limiting on my version of max. They seem to only respond to "mode wrap" or "mode fold" messages, and the Max 7 documentation mentions nothing about a range message with an integer. So that's the first problem. They are connected to "t b s" objects in the original patch, which suggests to me that maybe this is a typo -- that it's supposed to receive the SYMBOL "wrap" or "fold" instead. Okay, a typo that I can live with.
However, this patch still doesn't work correctly. Wrap mode seems to work like a modulus, so you'll never output the max value of pong, but fold mode will include the max value, bouncing off of it -- this abstraction is only supposed to produce indexes between 0 and (range - 1)... so it would be between 0 and 15, for a 16 step sequencer. In other words, with "pong 0 16 @mode wrap", you'd get output between 0-15, but (pong 0 16 @mode fold) will output between 0-16, which would be out of bounds for the sequencer.
I'm assuming that the operation of pong must have changed between Max 7 and Max 8 to account for both of these discrepancies, but I can't view the Max 8 documentation on the Cycling 74 website.
I would love it if someone could help explain where I'm missing things here, or confirm that these are typos or design errors. I've included the patch as it appears in the book on p. 64, a "fix" that hooks up the buttons in a way that works for me, and a test to show the eventual output of 16 -- I've included the "count_by_wrap" abstraction as a subpatcher.
Thank you, very much, and sorry for the novel! I would appreciate any insight from anyone who has worked through the book.
zach
Hello, Zach. Yes, by briefly looking at your code it seems there are errors in the code. But this is pretty expectable in the first edition of the book. I think the best you can do is to send the questionable code to Gregory (Gregory[at]cycling74.com), asking him to fix this in the next edition and in the downloadable code as well (I'm pretty sure Gregory is very interested in having the code bug-proof and tidy).
I don't have the impression the object has changed from 7 to 8. The pong reference for both versions is identical (https://docs.cycling74.com/max7/maxobject/pong). The mode message works only with a symbol.
Maybe Gregory had an object of his own making—the pong object was introduced relatively recently—that did respond to the mode message in combination to an integer value. When the code was updated to include pong, this discrepancy may have been overlooked.
The difference between the maximum reached value between wrap on the one hand and fold and clip on the other in rather logical mathematically speaking. Maybe it makes morse sense to view it from the perspective of a signal that is folded to a 0 to 1 range. (Take into account that fold always outputs a float.)
When wrapping leads to a sequence 0 1 2 3 0 1 2 3, it could be argued that the folded version of this is 0 1 2 3 3 2 1 0. In both sequences all values appear equally often over eight steps. This type of folding can be achieved by adding 0.1 to the input (and converting the output to an integer). Otherwise the second argument should simply be one lower when folding is enabled. In that case the sequence will repeat after six steps.
When wrapping leads to a sequence 0 1 2 3 0 1 2 3, it could be argued that the folded version of this is 0 1 2 3 3 2 1 0. In both sequences all values appear equally often over eight steps. This type of folding can be achieved by adding 0.1 to the input (and converting the output to an integer). Otherwise the second argument should simply be one lower when folding is enabled. In that case the sequence will repeat after six steps.
What a great solution, thanks JVKR! A quick and logical fix!
That makes sense with the pong abstraction, and having his own -- I noticed that it seemed like there was only a signal rate version of pong until recently. I did email Gregory about two weeks ago but hadn't heard back, I imagine he might not have seen it yet. At the very least I think it would be nice to have an errata page, like a text book.
Thanks to the both of you!
Greetings from California (a brief escape from the Polar Vortex-afflicted midwest).
Thanks for the feedback, Zach. Problem noted, and it'll be corrected in the next edition. Hope the rest of the book has been useful to you.
The idea that wrapping should have values for a sequence such as Johan cites is something that Max nerds discuss and argue about with more frequency than you might imagine. I am of the opinion that having that sequence where all values appear equally often over the requisite number of steps is the one I'm most comfortable with, and I'll update the abstraction to reflect that going forward.
Your mileage may vary, in which case you can always repatch to decrement the pong range.
i never understood pong and i never really knew the correct terminology for "fold" and "wrap" , so i always had to do things like that using expr.
Sorry for this necropost but could someone tell me 'where' to add the 0.1 to get Fold to behave as described above?
Many thanks!