How Long Before You Start to "Think in Max"?
I had a small plane in the 90′s. I was really considering trying to learn how to fly helicopters, but I remembered my instructor once telling me that it was way easier for someone who had never flown before, than it was for a fixed-wing pilot to make the transition to helicopters. He said everything was sort of the opposite of what you’d already worked so hard to make second-nature…
So I’ve been at Max in earnest about 3 weeks or so. I’ve got the obligatory "100 hours" in, I think.
I can say that it is really rich, and tremendous fun to learn. Having said that..
I’m not a talented c, java, basic, arduino, etc. programmer by any means. OTOH, I’ve been dabbling in computers/programming since 1980, & I can usually fight my way out of a wet paper bag, as they say, in most text/editor based languages if I need to get something done.
I’m learning that, in Max, for the most part, if there’s a will, there’s a way. The issue that I (and, I have to assume, countless others before me) am having is that I’m still trying to solve problems mentally in traditional programming constructs (if, then, for, next, do, while, case, switch, etc., etc.), and then finding a way to make Max emulate that functionality.
My instinct tells me that this is equivalent to walking out my back door & around the planet to get my mail across the street. IOW, not exactly efficient in either code or development time.
I’m a little frustrated with myself, and I guess I’m just wondering how long it was before some of you began to "Think in Max"?
Thanks for reading.
I’ve tried to teach Max to people who had a text programming background and have seen the situation. There is a different mindset for dataflow programming, especially with regard to things like loops. How long does it take to get over that? I’m not sure.
Maybe post some patches, or problems, that are frustrating you? For loops, Uzi and various data registers (coll, float, int, zl.reg, message box) are important. Although, thinking of looping through a pile of data is much less "Maxlike" than operating on a continuous stream of data.
This would be a great area to expand in the wiki — tactics for moving from other programming experience to Max.
If you can manage to think of it as a "math/algorithm based modular synthesizer" you might be better off than bringing a block-based programming mindset. Max’s roughly data-flow paradigm does take some getting used to, but like traditional languages, once you start to collect solutions to put in your bag of tricks, things get much easier as you re-use things. Like any language, proper abstractions, and the occasional code-refactoring session will go a long way towards keeping things manageable. Encapsulate, abstract, and don’t optimize too soon.
Max has some implicit "hidden" things that can bite the novice, e.g. the right-to-left, top-to-bottom evaluation order. This forum is fairly good at helping your figure out those sort of things (and the trigger object is your friend with controlling message order, BTW)
Scaling your problem size to match your ability size is important when starting out. You want projects that will challenge you, but not overwhelm you. I’ve seen a lot of novice Max users who embark on very ambitious projects, never to be heard from again.
You have to learn how to program things from scratch, but you don’t have to build things from scratch while learning. Grab examples from people and modify them. Cycling has the Tools section of the site, there are examples posted on the forum, and many users host their Max stuff (my stuff is here and here.
Thanks for the detailed responses & great advice. I've been able(for the most part) to find analogous structures to the things I'm missing from the traditional syntax's, I've been reading, trolling, reverse-engineering, plagiarizing, etc, like crazy. As you correctly state, the resources are abundant. The problem is me, I feel as though I'm moving at a snail's pace. I am amassing my toolkit, making elaborate notes on my favorite objects & what problems they solve best, as well as checking out the "related" objects in the help, etc.
Since you asked, here's a small example. My goal at the outset, which I think is modest, is to use Max for Live to enable me to design a proper arduino-based foot controller for live clip-based (as opposed to the looper device) looping. By proper, I mean Live API event-driven feedback to LED's on the pedal board, including the blinking status of fired/cued clips . The looper is 4 Tracks x 4 Scenes (for now) w/ 4 track footswitches & four scene footswitches. Basic. I'd considered trying to learn some python & do this using the framework classes, etc., but I'm thinking (hopefully correctly) that the time invested in learning Max will pay off down the road as my ambitions (& skill level) increase, and allow me to do things beyond the scope of python/framework/remote MIDI scripts, etc.
Until now, I've been duct taping everything together with a combination of Bidule, Autohotkey, Clyph-X (all brilliant tools, btw…), but I'm seeking a more integrated (and hopefully bulletproof) approach.
Consider the following subpatcher, which is one small module of (of many) in my device. Although this is a Max for Live device, I'm posting about it in this subforum, since it's more about Max "zen" than Live, since I'm not asking for help w/ the device(it does actually work…), as much as a sanity check on my approach. To me it seems heavy-handed & clunky, and lacks the minimalistic elegance that always impresses me in well written code.
This subpatcher accepts two inputs: A two element list consisting of TriggeredStatus (generated in the parent patcher by a live.observer, and TrackIndex, corresponding to the track selected by one of the four track footswitches.
The second input is a metro-based "clock", essentially an 0 & 127 alternating on 1/8 notes.
Any data entering the subpatcher does two things: Fires all the if-then groups, resulting in an output of four consecutive cc's, for LED control. Because only one Track has been selected ($1), the other three cc commands will be 0, turning off the previously selected LED. A signal from the "LED Clock" is then injected (or not, if the switch is activated on an exact quantize boundary & the clipslot never flashes…) into the MIDI datasteam of the active track's LED, which is then disconnected when the router is cleared by the expected change of TriggeredStatus from 1 to 0 when the clip starts actually playing/recording.
Yeah, it's pretty basic, and there are potential unhandled exceptions (accidentally stepping on two switches, etc.)and I know the proper way to do this is with the arduino handling the flashing logic, and Max simply providing a third cc value for flashing, w/o the clock hack. But at the moment, my "footswitch" is a TouchOSC iPad mockup, and besides, I guess I wanted to see if I could pull it off.
The thing is that I could do this without using "IF" objects (which seems almost to be frowned upon among the Max elite…), but it would require more objects. From the standpoint of efficiency, I have no idea how these objects run under the hood, so I'm not able to say whether one IF object beats a Change, Select, two Messages & a Trigger ( I just made that up, not saying that's the alternative, but you get the idea)
So bigger picture ( parent patch, design objectives, etc,) aside, is this approach reasonable? Heavy-handed & clumsy?
I do appreciate any feedback. Thanks again, sorry for the length.
----------begin_max5_patcher---------- 1612.3ocyZ01aaaCD9yo.8+vA2hkM.WOwWzKt.8CasECAXa8Csa6CKECxxzN r0lxPhNMcE6+9NRJkp3ZGq3PIGfDSyW087vi2c7j+xiezICljeknb.7b3ugS N4KXKmXayzxI0MbxfkoWksHszNvAY4KWJT5ACq5TKtRa63OTqRy9H7tB7yyT SEWMDJyKzCguCxJDoZAjtZUQ9pBo46+1Yu5LHK65kYgTIxxWqrqEst0Y4JsJ cov9.9IblKtdBp0KkpEBsUpH0sJmZGZ9jO7LFo4XyWqqGbPyUuT9u1UmPGcc 6qR0YWHUy+mBQl1wNDRB1OPRpJhMEL9n.38WuZEymXW9QA1V9uG+HSIVL79S tmovtPQBVHK0OGIY474hh2pS0qKG1fyguGlKThBjhmBe5BgBRgrExUmBxxpI gcTZmGjcQpZtn7GF3C5lN1izcXfge4lAAgQ1Jzfdir+khzIaRwxY.AzFBs.w l.NW0fz04tVKL554JTSVirdd1GOWgcouHUCqLGEFBhEkBrKQZAjtXALAU6+H B8seLf4k8kXetuvFENDhY1MjP6YAdhu2WThOgB92tsngIdQSkrKMUxAvHTiQ .zh.wVP4eqpp6An+7JgaFClfm5F.u267iSwL.H2YVhsMVJXGrD6PXoPKw3La 5za1CIMXX0+c.Qs14oJ.B7h9DeGDE8fHJq1TXjoHZbKHJowBlq3dPU6zVn0O 8Ke4SFB+YCN4dc7icmLHEb69k4biEoJ8KBcry8bu4p3cWHLtFLNTElQTBons +TrPABbAVWJuT.EoSk4vj0ZctZHnWWnLtxyUFGJvu95WAyxKreuTr.gF5gVa btfKxzuN5YyrtLxwwUfNjJkpLgcRtw5blCmOPbIJGmO.c3CFw17TxsyzNNbl SkylIJbRvhOCR0WWEowc1SFct52ey6d8yg+RbZg.PLfisVQ3zRf7LtShsKno 518eM1KpKTO5+hEZs.QiCcmrbZMLROpufaKmimV+.JSk3tDpmP9wDPkqEtPF v8CaLCUgHWJmqRwc8YUaR0gvY4dbu.0d5vXnI9LFZFOtQLzLReGCcsFLFjFZ KCdyZsWrmk3SJJJwXNii5mTdTvXtwWPeG9qwfzKsphmo7iEeOxPbJwpDE3rz 2UjyRQYY5bw2RN1X2uEVA947ES2N0P2VrCz6TrnAsJVTNq9jEVI51Cy5dDyv t4npq.8TB9m+3JVjO4p3JtxVDG2wb0sFydAvA9gwSgagm1EMEdOnImMa2E+t Y3U6NxcODA+NUw3dUyJNviZVUWEj6xdAiZLneLNEx7JEEE4eJhEGcboHpeoH ZGPQjiLE4YS3LuRQzQw1K+E1Kbztrgi2+6oRB7hW.LWFBIzXWh97T9EhuSjF qUVmBp734hehbDIMZ2PZb+SZLdzCERizIjFKz+jFMI7gBoEzIj1XuxYtTqS4 8CmYQ11gZv17vkrOrtsPH4iRHTysZcnIr9yaGS08UeMUiL715ziYe2Kf6kub lZEdS99hBhYG.EvFG03Rq2GF3F2M+fwr6o0dU7X99tA+1.My89ghQuzU4xXa HuI59ZxYLoWDw5okaBR2Dso5ZyWbsUFLcrAzKyWWjUyq0Qg.MDgohRsTkpk4 pFix.5li5B4zoB0MP8R4zU4RktRRHT5HihNsJtVd7n5ZMdXxxzIKDVx8VxOQ 6ASXa.iI1z8.FuKXQsRv5c4hSefJW7VIWGAAKtUGWB5cAqUJXadXe+GioI12 xMkRcwuT4R9F0pRkc8AdS0t6HtAmDObBeSbN1kA9pToRsn1VqagB0C53a.EF dUQivGcCnD04Pg4gSEaBEWreblEQUPwVqCgBsqbH51HXwM7GZq0gXIpawx3j lXYbRWhkM0d7LV3QU4XxEn1Vq4vosVGhSVacIy6UGLsWtXOPkK5CT4hzqx0X OEnfukKyuwp86Ym0+g7Ytn+9YL9wgv1qbQF2+BVqTw38+sv3sQCa7c0ARh6W ckKaUlnfqq0g90akJI4tGuEeDyldppeSPQtehqgcIVZ0lxlW6ps6J7.Ziffs 0N1HgeXHgwahDasiLR1LYKs9jRbyKlXq0NjTktqzUqtTTTVILNPLXY5GxKL0 iF5pKUt5tT3MnPbordJUMkVjcgTKxzqKb459pjHSF1rOP7i+G5mlHX. -----------end_max5_patcher-----------
I have no way to test this so there might be bugs, but this is roughly equivalent, from a more data-flow POV:
----------begin_max5_patcher---------- 944.3oc0XssiaaCD8Y6uhApEMonpFh5pcdqXSQgARQdHE4kjhBZIZalUlTfj JYSCx+d4EIuqRVw01Xii6KTfCuclCOCmw9SSmDrheCQF.OCdCLYxmlNYh0jw vjt9SB1guorFKsSKnjuaGgoBBcioH2nr1eIq9ifpUv.950fZKAZDj2S4sRPI vkW2ufFrpbKks4eDjRk6fQoKlEEBwIo1OQH6GcK72cKhVYOC9p28qwQ86zZN Swv6H1gdMQTgY39wXs63spZhxB5n6rBI8esq.EOauYwlU1os2hd4TV+pQFae d5TSS3AxRtC2iOWjYbxjrjYEo4QKR0Nr0ho89bazb+t1PD2Yr+txrIWc0O.+ D7ZbMrlKfW76O+IxfSvwXjOngyWc6uAqHd71NeKpv5zE9teQEG+8au+5Lo9X CwcrAA6OgQt5GPawm.eriHk3MjuhP9QDD4SxmDYIgB6mj4lVzhQXj7yIiniZ kZMCVQ4rA.1FilUXiQi5Z1uYeK4QTbwCFH0Qj5vIeDY1+qjViDp8K.5goitH s3YYiGo8XFnQMux7chPV0VdMQAwGBu3Rw3DwiwKmP3V7npjviUobJYaFKm7R ldDMO.0To5YveIna1PDuRGb2JC0c0okWxpH2.OE1PXDg9Q7J3CaIL.Ck0zlm .TY2hzCHsqCJ2hYaHxe1CYmYCFSisgj4tW5hFIc9h6ks+MAEWeojLeDcWKqQ SfPj2G5cY9PY4lO4K7QEoGKSD6KZL7DBJeL0d+4xmuDtsniW15qZHjFQEYCq GBk4U3L+xW2LF0nK9Btplq0NKYdHkDWJ2BWNM+rA5xmMrq1WjR5r4nXsHHMp uP3wKGNe9ImtdfiDcOUJ+JRsFT5G7rOPBtWHWxZzJ3uAtcBJ81aY+NcQxQ5z qzuTeDN9.c4ind+OD3UeYxG5Z.Y9UhLPngMAdK6NoiTbmUg9wiRNioIKc9HM vdKSOjZKVAMbgJLDH0RhdHBV.35ZXUMkcsle6gftKoj257uDOIrRLEJ0eGXq FOsXjDVEe+B0r3w5TewOY25RF6Cucj7VQYuXnuBX3V2phHUTlsT+6No4ClzV ZUEgcWGohJwqpIVNI5d0IGLdxuvvSwgfmryFdLQ7OLdLfF4AO6nUMbcw.chl jXqZGsvUeV79N2dNOZNP5gh+yCeleYc8lO3haD3je9TaG.6b9PS5APNmQky7 CfbROQ33dWG2z7dhP1skVjnyu9NtvzMOz1kxbcs6Xf4OXse9ESM61mm9e7hF QbN -----------end_max5_patcher-----------
more than a year (assuming an average use of 8 hours per week).
Your example doesn’t seem to work the way I would expect from your description. Do you want either one blinking light or no blinking lights, based on the input?
Based on that idea, my response seems to be a joke about max programmers:
----------begin_max5_patcher---------- 1344.3oc0ZssiihCD8YxWAhG2MSjsACj8s86XznHRhaZOCAPfS28til+80Wf zlDt3.jLrOzHkx13Sc7oJaJ2+bkky9rOHkN1+k8Wssr94JKKoIgAqpea4bJ5 iCIQkxt4bhTVFESbVqZiQ9fIsCrg01xiXGdklFuqfbfod2Xr6F7ZarKZCXsM +I+GvvM.6uUMlzymxNyRHL4r.qr9RVJqj9uDoMwPUloGkSY19u+kfsNZ8MM5 jruN+cAMJ4BdJHkjTVDilkpiIOvl.In7DfBT83BjT3g8O4DU+cbzQKMsFrHg sesZk3w5IxhPaTOrnWvVEhCAyMMFNZZzCGp.EGbKGZDzmXD5UsvimaZLX7pw ZP4AVPzXuwzdAaPBD6O6A09SfFkLG1GtfXQ29ho8kgMO.sHdXR7QRGrr33DR OdtOHT3xdA3MHOevVu01H4BFBLn6q6mZZzBtWxHE6HoQ6Sj9DnKOklx5vYgi vYSIuywxMK8bzTjYivfgoALPpX8wFx.CK.7CFg.XeTZ7LJBRHG6y0gxcdC.a qc56cw22yjE+NxUDnH6.rg6+OuRl9oFbHdpTCdJTiq+xkZv9SkZbmB0TIZw3 EH0fBlJ0rfylVvmVhM+Hx1t1dCyB99JcR3.r.17Lpfwrk55q9qcdBOe7TtMu WIYwzCFPRHoZ1Ob111AGLim6PG+jhJpnhK3S.Mg7FonjGfpgQKmn7bMyVZCQ PfeOS9h7WewDMUYBdwTA4M50uV96sfyhLNEdtP4Tev2+Q0HeQaU8PqoXnm7f wPOEEqNXuWnFIyWfiSxN7CxQsnKN8jSRoo54eZz7QxKQmSX6ZesnY6uDcfz4 facwwxItfdLKU.hFiTXtd53NmL8m34mNirGoQ4sL3RtebtbeTgfWqxlfpajk kkzroKKk7.fnT5oHFgQUfEAt7RomxKjYdzlHUxpWKOTjkjz3UoZ4sVZ4He09 .4c5Q1qx2kNUx6NMudIv4BGcjFSJYMswhhKaZoQ0Uzkg5Q1Mr2WDdynbl8da pdKsDjGHkbPf12VnGi2RbNRqkNzWWEuCcctZLsKq593lqat+QG6gXUmerJba 9YzXtJa.BU8UZnpxX4ccRytSbdODJZBDZOrH54vhkuGkO.Khkxx.EIt0.R79 UkSQTJDiCpImS1Tg.yjdpuK.c4YOrVW5KmNiyzZ3P1oSjzpLbynu1rJI2T1N tSId3Jd3coJdCjeSEHtUdfF8ZmLKgida+ec33eZCMJZD5CLdShQPhSMd72NO lG8CavfBxJtbKVURmGx9CHvxWPJeqFwUpSEaT9LX67AFOVOF7Dx2YBS.cgyD U3Og.o6gM97L+IzztNhqzSEs2NMUlct3PMzpOIocSule9aFM8xm.80OSIeUG ekd7XyO4PcJ8RwY9UeckQKpiByPCvr3TcKDLaLjcWLPVjyyHogjlgKCoAxTL unTFFE.tbTFhr+Fg4kCjaI80RWX3Ypxnk.0eaJC+6AyyQNC6usRuVfNkQuQN tiOE7c52EwXEz8mYpcK0Ki4TqW2v0C7NJhUqfnmIuqIMNIaeTRUgauL1VpU1 pOIw4o72+AGGAFbgqpOd715OL5Je6NlqGn6aN4Qdo6U+iXMlaHBE9.ugHYOZ dlRkaecvekyeSPePibqcDvKthBsNcSv9sA52rLXLdBWX3IXggG+EFdvKK73a x5EJ74wOPCvi+SjeD6c6NDd7dt3AMDdvOW7.GBOtOW7Ln9A9zvC1j3qq.8iD Ot.Sy+.eJ3AYx9WtikeTa2e000KfxUWS+UWQ+sWOeWWMOed90p+SxV5Po -----------end_max5_patcher-----------
Chris’s is nicer.
I completely missed that part of the description. Here are all the methods so far:
----------begin_max5_patcher---------- 3837.3oc6cs9iaaiD+y69WAgawk6w183KQIUf9g6RaODflqen45AbMEAx1Z8 pFsRFRxIosn+ueTjT1R1Vhb8CZZua.xtqdOyONCmgjyL72u9pQiy+Tb4HvWB 9IvUW86We0UhSUehqTGe0nGh9zjznRwsMZR9CODmUM5F40ph+Tk37UEQSdOH NKZbZLXZTUTycLOpZx8IYydWQ7jJ4WBSX25cC.CuEdC.gX0+BitEB9Y0yjLU 7NyG+KeA0q4EcWdVUVzCwhK8iwESixV9QxV7P9hpz3JAQBa8DkI+l3IP3aaN 87h3RNKDUkjm0GU07ikjzcEyFKd2KeM7uYRVymDUet+35qq+wM6ITNNMI68f Io4Sd+.fHMfrhb8oChgzCNFdDfiz3oCvtLHolEIAXAmBa9413Wh214IzxWeA GCphKdmTdsM+Ju8pecdr76NJg2Bs7izinCCF1h31P14HCMdxVeyfFlkgFu.3 oDZndlCM91FZ7PmRnQ1uqYPSfsgFL9nBMYwejyWazyaAmXiAH.FP.TCvNhPs GQ7FD7B2Zuu+ihjnzsCqd8AcitYs+ux7zixTWC7Jo+ggWuCG7Nuf21Cd32FV tjH6nW1euu2fF1fGbCa6sn03EUU4YC1mDTX3VYydPEOJZXEuMjPFGkMSu1Ek 0hBN7ZWODWVFMKdi1eD.NDt3Ezhp7jNGF1Ctfe7M78hY6rVDiZLLhOfZQf27 cu9cu9+8Mes9dnvxtlBFrCJO+GaGT6NT1ETZS+wEJnPgE7WQRZ7GhKJ4ndqO 5UihlOu0oup0iTCf+Rt3EwtY4oRxjmBt7TEweHo448kmj2rbcyEa.QDUzMIh JZfYTQSLMnELxaBmU6md7z1efQ4yiyRxZK1z4xSiuKZQZ061NF0852EMIt2G dqsUWMZVQxz7rZhnySVe5lOGm4DxD0+bEyHtirn4a4gK47whxwQE0HmxDOt4 hU44ocuzxFKtHdTVxCQUwUIRhECW9RSdPXRnyGR5Aw8kSJxSS67pjW4Ca4JS 4smSh+Xxzp66Lnj5qvu8j4MMAiVhQSSlEWV08bUQyJ6dlNCOtsfVac2NmeHc 30FwLXLHo8U1hZrurWPnzKVby.9V1hsllLhz980uDxlZz3VWY6FUtoqmaCnj 2iQjqZ5ATotc3QzYboLM.pxUMhz+G55cKtAfh2U.EMDftanH1NnX4GilqAEk Fm8kfXnNP73HTVKLtOxjGRzTRblI5orEu7m8J50OtzudVqKzL6Rh9yNf7ZWm 61vAONSU+CR8OnK82SS+aDw.gC8EGDzOlPCe5oN92.HizFQLnYFInjiBH5DJ hCfiyidO.pUfrYXGdqFCxPXIFdgJPJdqFgURuh02elm2AAL5vwPKzemIHgpC LigB1gRGamQiU97mlj0mKtBNs95aGlJyWTLogzZb+Dzkq49eWkjsbHP+zp9w W6FuOY5ztC4P5kdYsO+xQWYTi5NQyHCn4ZWAcDZ1XRl3LjbcGkFIZHfYjaHZ fMklcJICiT.cGIiZ6BFQytCIuktubcACpoRFaQQ8jIYvdLz7gnOCvOec64Bb TYzGhm9N9mfao+cQUUEIiWTIsV1dhJ224qS+7A9HlDqsRDC7w66iNKMebTpZ pYW9raYtxtdEHdPWfRDy27EnDZ4EnDy7NgqcKhDXNzfrMzPXmRnoSnXnAZv1 FZf9mPnoSjXnAYHVFYP9At7B9qfNyVuepysd+MnqkWu++Jmz7GJD1XD45qI9 Ecvk5GGd.Ww2NRjFsRk6.nTkOaVZrArOJTuBI9nEANG4NcHx46l3a.SxnmqL oGyblz6bkIw9lyjjyTlDGFXNShbVlbOM20fBRO4zXuiAOc161aKW8EpReE+e eA+eCARHwxGivnUKFZewqD12lwqzQKxiDwuWMrTCOF.MRC6H3fQmNh5dAw2f .vjwOLT2jx.qg.E8cvBFj0ImYr929xA37PVq.2zaXFGeFF3lH9n2LMvMQviQ fahgviZfapEBHX4xK6izCAg6EBr27hoteuhIFv6a14lkdN0TjC7fP8.PPn9L HBSOf1u51PerrgsaAgbiuNlDDxdNPLHqljTrO93DCx6FJRZBwcjAgx8kfmQU fTv3AmK6vVNDQFVWaGbJ.OjG0Od8sCaP+SFBXjQZirOHYrK0qOznyJIk9vC3 v3AMvX7.eQfG7QipW9fgziGnvKD4Crd4CSvCL7BQ9.oW9PkyXCKe3egHefzK eXDdDbgHe.0Ke3Y.bvtPDOf5EOLAN7tHlwJQtx8x+4q0OYmpbBI.MnuYmNPw wyUNYh5pVKKWNU451X8bxx4PIK2PoVht.2ODea.BWOnSZO9N26j5nSg9xJ6t hSAlik31o3EZ.rjt6XoQodnSioUfjVQ5P+thHSIaYrXnxsjgvTxQBS22LmCY KTUe9whnswzMmWkdGy7wRN00A04QKKpTZjSILOCkSQWr8i1sBc0EI+9rzeET snHCje2cfp6iAyqcUJeQIPTKzzfxXYpOprVggHsvLb2gYnY33FE0qiqXpQYM qRZjR7u0mxfgTixc1fCXxy9xW9Yf+D3GiRA2kW.9tu4qeQ4HmIe1a5.TYn1W mTDx+hUYcHuG+bjVmdvppwkp2uf0WyhdmufmbH4miMzBhR00SKT58TzSb8I1 ciGiJka4RuOfx8wR210Ss6wKl793J.1X.k1yRduQnscj7Vb2GQCxRd27pL9U 4fGHMor5KAuoHY1r3hePLuF2vOj6fyqxlF+IveFLKNKtfaoZJ3i2GmAh.SRS l+BPRo5g3WPNeHfI2y8RNt7unqURsrwBiYdL8Ig+NWUHbS+hFPReQVsC7FTG CT9EnfRl1ZzB0IqQK1RZ+0u5qeEXkede+BcdkhwhZUWauRQ5qVDAWVxoCgnb 2jAurd5dAuJSCVRkZ3AROtzihnKKTzn5KA2GJ4Lx4YX0ChEXupswODmxoTd2 7ByB.ocgWkMmqEYYbhpJ2gAlAR9DqVGN5nSXI8v+UQz30sdmbG.UOgEY.Y9. 71rV1yqxkmsf2W3j7rLN1JKE4uMieop6ip.yyKpt4FPbZYL+RwQEfnzTfnpk mTOKXqHi5j8dR9BI+SzY0WTMMaZ6D+h5OfUee2refiRkUoVc1rB6f6TwALrH k36LTrugXLyYnXloEBFlSIVXToyvgjKHOFZ1j5PwCISmmyMhn5cfRkERXY1g i7IKOp6G83WwaLshafBbmB3j24GMiQlRydtCNaZ2iX2oPYgMsBNgQtEMiLkl ciJkElb9gyFWbgbnhnF47SzvT68X2wyUrwzr63VElY6dmsVsxZ8.1yxUKq0+ 7mv5k0fA452lWTvYuWFUosN1nB0UDxevbz84Xc0jXc0OTln23mi00mi00Cyj 18ejqxypYk6FPY8btUOkbEwbDCvE0Kx4PT8eKV7hIS5cd2vZl2Mlry.YWCn. +l7Go2x4O5oyxXbJWFzP5pXZ7I3pfdYLq1ghRFAy6LeRsONg2q1PjTtjfPUP ancgAON6NDcReZWLldkx6PsQ+hJQmjk1JU8YYH3bm2aCHZi8kcN9WHNVbVzj W+AOGlElGlE2TGkE5Vx6.4tAnJNVvg51aX1889pd65D5p1+dy8w016p8mHt9 lJAQbCZQ7ekAh4uiEkIeHFTDMMIGHqoO2HBU8ZOYxyDAqd8hQWGOy0+cYyB3 K2Duixlt5tu6Ngcvb98UvsxVljMIV7Px6U5KC3si3iHKq5si396.po75uRt3 IE2G+Imlb2cwERJH8WAIYqdKI01n+raea1+96ey27kf+a7KJhAbdfeuMhLun Df9BpjhEuv5C60nbnlvDPEs8pZmBTUG27OF6CXmeNW8l64sguk2aR8L4TxaR 4BUn+d.HKuJV5zDuwS30jZrGkIyxh3hH2oZQab2UzPwa39tk6TkO5AmPBQsF bBAocvInmPCN4QG0ZTjHDhob4d7yQs19F0ZxoIQ1UxSuvVanbDPL7ICctWFw VxQ4Vum01qmSZ5AF7OySmd3SS.3oOiKZFuZclWnyEeBRgpBul780gpD1kLpp aLSE.JfZHhJs.4Sz4F59AndFMxI8ifZ..1yRhsT8RqH0DhH09UYr+.Rq9vmp 8APLFLIxJNqdvjwdpBlXyASnof4SVqSHS.S1s9hwx6aFZRHOQsJwGS+mmf.e 0WAHxoxlOnT4LRCMTfMLr0dA6Po1F0216bojS9DktBdw6H7pRKXCfW5SY3Es avKtwgUsvKw6oL7BezvqJPOXFBugWnnqI4PD2+IYpVICRlmS0pdl+CYIdSM+ GOYx0JipYIpcwLJi9HpYI9T6WyRNN6BzFuU+5P6BzPCirVh6DxmHS2EZoNzN WsoAJtuogC7ZoRChwtUT45TCCNDcayQVNWZHllWJLGp4gc1kBblllgDucTfR lo+psxf5saglirr7joLJktWLJoYp38Wdjqxn96GiF1gQCcWFMb+jbgxEph2w XyQ1lOwme8pXZJfvbHZ1zDzyGd1kDVDxtoCTumUJJZVpUXPMN3NGo1Teabbf DZcEDSSiai8TXcTfJKscv11vDGcBXT7gTqZcF0SjH0DVGFkcZXTxgTUbcFU5 dKEqlKcAiJNx1LJ9n6PurQTF.fJ+4EGYaNkYINUlOQMbZHz9bpoEaDzNJ85G bKQLEax.viH2WEY9tKm5NImpOzNhgT0VZsL6f19QRQTwQVtgy3RxQsRK87pJ hrosiyBRFe9QxtQFxGdn8A94L21ZYtsn0n6jmKSj60EBToyslJmQe4rem6Yi F8Mav2HuxMkbPFPMds0bN4TSWePN8jia0VQnVibvgl.OVS1wHEKj8PGSnFhS QNT60VY.0D5TXCC5V5UX2Ruxy2sfGOeqgOqw58nZYOwGynGrigOH2BeH1q2G hIxyj.6ROHcziucoGrN5gYW5gnid7rG8PMQ9gXW5Qq7C1tziV4GjcoGsxOVz cCSjev1q+m09T8PO1q+Ygme5ZuXT6RO5jmYd1kdzouyH1kdz5NuEGHnI9afr 3v1IFzdgsn+7lLsFXcxOSxSk01ueB.uE4iQXL+AtkFfXrv5+J.g7Yd0+Eokx ygatYBuH3B+KBtfcQvEdWDbQvk.WfgWDbA9hfKLR6dWsmJWem0Jrr0jxZET1 0JlrqWHY4us+35+e+dZmS -----------end_max5_patcher-----------
Wow. OK, where to start….
Roman: Would that equate to 6 months at 16hrs/Wk? :-)
mzed: Sorry if I explained that poorly. We’re looking for three states, hence my comment about eventually implementing the flasher in firmware, and sending three different cc vals, i.e.
We need to represent three possible conditions of a track (clip) at any given moment. If you’ve loaded Chris’ latest combo patcher, the one thing that is CRITICAL to understand is that in vivo, any incoming data from the right column would, within one measure, ALWAYS be followed by an item from the left column, which stops all flashing, and leaves only one LED, lit steady. Normally, this would be the corresponding item, i.e. 0,2 for 1,2, etc., unless one had made a mistake and hit two different switches in rapid succession. In any case, the most recent TriggerStatus change will always result in a cancellation of all flashing, and the last man standing (solid LED) will be the last active(selected) track. Put another way, the last data packet into this patcher will always have a 0 as the first element.
That considerd, the logic on the TLM_ForestCat patcher is providing the desired result bearing in mind that:
A: One (and only one) track would always be "selected", as indicated by an LED
B: The status of a given track would either be:
1. Not selected (LED Off)
2. Selected, but "cued up", waiting for the next measure, etc. (Blinking)
3. Selected and playing/recording(Solid LED). For the future: Using tri-colored LED’s for record play status w/ an add’l state/cc value. I’m just getting started w/ this :-)
Like I said, it does work, but it strikes me as a little brute force/amateurish, I guess…
Jeez, I barely had time to think "I better roll together a test jig so these guys can see how this is supposed to work…" and you had already done it and posted it. Amazing.
It’s really nice of you guys to throw your hats in the ring, I appreciate it, and it’s fun to see how different minds approach it.
It’s also sobering to see how far I have to go to "speak this language" natively. Chris/mzed, if your patches had replicated all of my functionality with that few components, I was ready to hang myself :-) But I’m keeping the rope handy…
OK, I removed a couple objects from my solution, so it’s now closer to your solution. The only thing my solution doesn’t do that yours does, is allow for multiple blinking tracks.
----------begin_max5_patcher---------- 3716.3oc6cs9aaajD+y1+UrPM3x8v0k6Cxkr.8CWSaODflKen45AbIEATRzx rglTfjJIsE8+8aeQIRYQtikknonc.hs4ycle6ryicmY4eb9YSll84nhInuF8 VzYm8Gme1YpSIOwYliOaxMgedVRXg51lLK6lahRKmbg9ZkQetTc9x7vYe.Ek FNMIBMOrLr5NVFVN653zEuOOZVotkHD5ktWfnrKct.gwdxeQvW5f9EyyDOW8 Nyl9qeIys5EcUVZYZ3MQpK8yQ4yCSW2HoqtIaUYRTohHcp8DEw+t5IvjKWe5 7ESU215yHd73zpmFKO2ed94xebw8DUllDm9AzrjrYenC7fwc1fGbVmvA6T.N Rhl2A65FHaJDMP2w6T8ycwuT2cyS30u9bAFTFk+dsnWc9Ue6k+1xHc6NIVzC stQN1LoGFNS5cpxjTBbljepxjNT3Lo+fkISi9jfBukFpbQyFgvHBhhX.PAW0 uvT2Nggfcpk5elGGlra.xsMPXxEa8+0sWKpyZ.TtGNfZYtn+.cyu2srhV7fh 4JU4tcpJ24fqJ+dKjLcUYYVZmLHWZph36aev.C28fga0WOMLcwATh+lnhhvE Q2pmjgb5hCYt03PWEGhCZgCI28tvV496ljM4.JYidyO9p2+p+22+c1G+SXAx e424veW9cc3+gBTpS+Q4FnvfEhWQbRzGixKhEh3aZzylDtbYsSeVsGQBf+Zl 5E4cw5SEmpOky5SkG8w3pmmqOona47pKVAhbtxFBlnLa5wTBWL+ZvnnKbgza wn40afIYKiRiSWlGUH7xLrzzRqu77nqBWkT99ciQMu9UgyhZ8g2Ye0YSVjGO OKURDMdR4oqZt2hvJYB4O2vLp6HMb4Nd3BAerpXZXtD4LlBIUWrLKKo4kV2Y IDwCSiuIrLpLVSrDm0uz3aTpoazPZKsWWLKOKIowqRekOtiqLWzeNK5SwyKu tgqwxqHt83kUcASViQyiWDUT17bkgKJZdlFwaUWPq9X2FmuqwvaEBFZJJt9U 1wvXLQKAR0dmRTp5pK+s0PYLs9KrcQjaOjlT6J6VS+EMcwoiQ4sXO3rJUflw aGdHcgPLyBhp8DBGnBaSGBWm.JYeATbW.59ghj9AEK9T3RKnn1NKWoWLv0FH dbDJkBi2GYxCIZpINPhdDeskY2pe1pnW63R6iypcgpI4PoP6.xqM8SqonCFI YJ4Onxerw0MaJ3ziGCT9gi8aGTXAO9FO9OPXPCGwN.sRvnGEPbPLRrCbbY3G PNVkHMXo1hqqiMcaDmQp.o5sBCqHvTn45dP.iFbrSOnvCBRPzwH.FJ7NTiw1 azXiW+Iwos4jqhSkWe2vTQ1p7YUjVEegZx0BOvKiSWGDza2LrAgabiWGOedy fNzQuMeYlfqMDHQLtzUtJDJIu.m0GzrMiKjgJnCJCjjvclQcAxnzace6lOO9 jrzzIHRFObHY5cQbZXPyPIYFcPQxXHBFCGRdGc3sPyDfJZN9zLFrnQvfAmwf kMH.o4sTni0yPIlqmbMlRgNu+UnuC5+3pcD8KmWedGmTD9wn4uWzBBeJdeXY Yd7zUkZ6x0mTz66bCZetGuCSX1NIhNZ71ZzEIYSCSLSC75mcGyK24a.wC5hF hcYvWzPmSzUFEq8KEFShOQYRMyAiGImn7nGGNORGqqvsADfs.2rw2Bb+2EMB uqrTxDbtqBmXct11jfC3Bi1PJ4Xs1nkYKVjDAf8oT6CRH9mnJBnbSB8.fI8X mpLIiBmIOUy+LJlAmIomnLIw2ENShGqFtpPgJETcZ4xy4D1xUaYzy2H92WJ9 WWfjdsLLniVMWao0CgOJRqGUBqIgEI7..ZzF1wNcl.xX1vKq05D.lM8ltTS5 nM3o0V542IqSOwX8e3Ecv45UM1johtcy3jSvLULfANQEwNOrIpnUdg5DnYFW 6LSvCKu.0O5MYJSGtQ6cpYxVPM4YHWGG.ARnSnxtK2CB6.ZIpYO8wxZTa1nw cl0slThDTV25dRYctM7fZIbaZUlV6BHOjGC9qThRPS6bJU8p4lBs6wM6goZR W94d2G6fOnicncAL9jZJTzYqSqt1hGECdb5FPL4jIH.gLJ.DQTh1kPz0iR23 ANXjHfPrKf.AOHNiD4Crc4CFGf7AejHefsKe.BO7GIxGN.rvD..O7FIxGN.L v.AObGOkH1K91WYeZHILkaZ93N8O6gCTF5kHlVxRKZ4EXJTL7vqBwZ1Y8TMh cpTiXw0h6rU8alLAfWKZ75CkaMbKaio66RxomJSLPUdGqNld6vWaMvjCMldp T6cKCWuooXQNk54BTNEu+X5.u5JZtCzzDIecZxugJWkmhxt5JT40QnkRqQYq JPpssGakhfNUJMk9sY0h5Dlc1eX1AFNdqMsliqXJnxwyHMxn7K4LOm.Fnhxy +.VUdu3EeA5uf94vDzUY4ne76+tmWLYvTnrUJ.0yzKkaSJByGsCV6phGeF1Z EkQbqu2BQ82dpgaMlrGcH4yH.sfXF55ZEJcGsP48pfQq7XzL3VWwncL39XM1 dnWxnSWIhbqDQ.CnZitbqtK5cj7VrQh87f4lXWd27xTwUEfGJItn7qQuIOdw hn7eRE53EhCEN37xz4QeF8WQKhRixEVpli9z0QonPzrj3kOGEWXdHwEzgbhl csvK4nh+lsdIttpd0IQgm8h6cuq17goeQcHouJU5.Of5i13WfAJ8BrggrA4l +PeIs+pW9cuDswOuWuxdgD6KUFW2qTr8pP2ebIm1EhJbSF8B4LpgdYpErjoG gqSRA.nHdbghPpacrvGJeLQHw45Bqz0876up3+mhRDTpPMuxr.RaW3koKEih 5YbhoWBAS5oYEj3zds99aLlnmFG9uxCmts063qPX4DVjhzIC86RqYOuLSe1b gtvYYooBrUuU69tTwkJuNrDsLKu7hKPQIEQhKEEliBSRPpck2X4rfsgLjU14 rrUZ9mZypuJ2Bq567qVqvVs5yGl5ANJ6XCbnEkrL998YGafoqoWhiNck4z0G 0yU3KGHi5MXJ9ZopVXEL9vgjgtgMPGTjLnJbe3HXv.Rx7AEECVKy.YKl.7lO BdXQyXnz7vXawfPNAwYxIHNigNFzc3r8i.0nMgLbnYn1.w9CGZ1suo4da6OY 6Deom2.T1t4e.2BT5LYw9gr7bA68hvRq64BlTFCi4cVEZOkyXPxYLt9qqhGw 4obF6obF6fLyL+G8T4uYpWt.UHmXE47tjGIPLjPTOOS.Qx+VMC0yl05jqPrL 4Jd5bM1WWwS95bvl1wlAM9wybU+PtVW02gyeDtTWiiotLPUTgdtm3yb4wIGN slGb508wwrx7VW8miyVKdiRQbHl3lZ4cGqo3.IvW6vRscfftfy8diwlZMAG1 6jbfNvVLc8xmiY9OsV5vWK8KjKkts00zWsL5UgpPBr8gEX++xozppSmgp8u2 bcjzdmzehH4MUfBEFzBE+JEEIdGqJh+XDJObdbFRuYWbgJejkdxjkpxHY4JN JSZU4eWTsJs5Opngoy2b2WckxNXl39xEVYKhSmEodH88p8kA8tIhHxRKe2Dg +NHIkKakL0SptOwSNO9pqhx0TPxughS27Vhk1n+hKeW5+90u46+Zz+M544QH AOHt2JQlmWfveISSwpWn7vVMJGXYsfMoTsIZX8FvClvOFeEYN8bt5MWK5Cem PahblbJDcoBgJ7W4iRyJizNMI57TdMYh8nHdQZnPD4JSOZk6tpNJQG2Ot9Cc 1cN3DZ.tVvIlMOmtBNA+HJ3j6bpIwvp7DkIj6IOkZR22TSxs1mrkGe4lTWIB tJ7IfN2qSKGymlZuN7bxhFXz2lkL+vmK3NO7oUeU7pxzq2lK9TrAUUdMw41P Up2XFUsEyTNhgX.QTsEHN0lan2O.0ETjS1ifpC.1smDaY1kVwlIDQO52TW+c HsxcdrpCfBFLo58TQ6fom2iUvj.GLcfBlOZsNgg.ldWxUwxygglT5iTqRhX5 eVLF8MeChpmJaQPo5Yj1An.afddR7rVZ1Lde+Yui9fOQoafWxdBulZ+D.7xd LCu38CdIUNrZEdotOlgWm6L7ZRzCOfvavHEcgTnHB+mz0SCk7T8zzw7evp+I q8QSA0.66DsY68yicG1XJ3r9eio3nTPJP+JURGNUP.3ZnwavjLv2IRlb5Qxz SORlMLHYneXM4r87C9nmJmVXtl8BJsttcdT.d8c1y0J1oXkWAkjwN6WGG2+R pxyFyWdMGctI0+ExmmW+HhR0olqQLTcTeyojdhS04GQEmRB5eN8V5ragQ2Sg Wy7ZxHlYORqCRdzC.iRfXQvaOYTWU41R8zKrno+0C+fziBoBo71yObvTldW0 xoAi57vvnGTGV2lQMeYILeg3HlfwabD0LucdWJUPqNrmQAFzJ0hOb9TsyfVU pdCnR+kbxUF6PqV4f8zFldGyg33VMFn5n9dH.P9jwuWLJMfUWim7ngJixteL JsAiRGtLJ089I5xqaCScTOynTuSNsJTnkrp2vozfozit+7FO.LKiu1gd0Q8r DEF573wFPUtsCzw6dCKZFTX+AOU41CsJ2V0azbxy0Ex81RAlx491wd3TObx1 T.1PS4s60ucO9sJr76D8PsQOr9kdv1nGZ+RON1nGbuQOtb.zCqwlcx.fdFZ3 iyvhdnA8F8rUS0B832uzisw6Td+RO1zO2zahiO8XS+Ls+rWPYPjen8K8XU9g zuziU4Gb+ROVke5O8gDH5eb48l8KPzCYXQN39ib7gfN8m0KBDqo39yaUhGD7 oGoGHZmI8m08l6HicMZuGoGaVKH7gE9PFVjS+Y6p4VDHn8k1cPOyxRza6WuE 4bIlSvDh3Atj4i87Bj+kOFy8bk+Eslg6CGWfGEbgynfK.vD8n0LHSsfyfhbX 8mqGPTE0ewYfCFCx+X+QAWvGEbg2nfKbGEbAD2T6MUePnFZ+ETADxASFVjy9 Z0Tu9NaswxJojs1PY2Zyjc6MRVwa6OO++CbPdfOM -----------end_max5_patcher-----------
Here’s a version with a slightly simpler TLM_CBM, getting rid of the bucket object:
----------begin_max5_patcher---------- 3723.3oc6cs9abaiD+y1+UPrs3x8v0GeIJoBzObWZ6g.zb8CMWOfKoHPdW40 pUVZgjbRZK5+6GeockVuhj65ckkjc.hs06Y9wgyLjblg+94mM6p7OEWNC7kf 2BN6re+7yNSdJwINSe7YytM5SySiJk21r442dabV0rKTWqJ9SUxyWUDM+W.w YQWkFCVDUEUeGqhpleSR1x2WDOuR8kvXxkdW.HzKgW.PHl3WXzkPvOoeljEx 2Y9U+7WP8peQWmmUkEcar7R+Xbwhnr0ejr6tM+tpz3JIQBa7DkI+l7IP3KWe 5hkWIus0mg+3IY0OMRbt+37yE+3hGHpbUZR1u.lmlO+WLfGTe3F7vmZDNniA 3HMdgA10KT7o.jPUCOr9m6heId6lmPqe8EbLnJt38JQul7q51q90Uwpu6rDd Kz5OxolIYH2YR1XkIIX2YR+wJSBItyjACVlLK9ibJ7dZnJ3e1X.BfAD.0ATv S9KDwyHLDtSsT+ihjnzcCPdcABytXq+u960g5rV.k2wCnVUvaO.29alkUThG DjuTUtmQU4vitp7GrPxU2UUkmYjA8ElpvAA16LPQl6Lbu15qhxVdDk3uMtrL ZY78ZIo.nINj50fC8jbHJrCNDu+Mgcx86mjM9HJYCdy2852+5+227016+iog heEXr6um+918+XAJMo+3BMTnwB9qHIM9CwEkIbQ7MezylEsZUiSeViGQ.f+b t7EwtX8oRxTmBt9TEweHo948Umj2rbd8EqAQeeoMDDVZ1jQkBWzfFvHuIbov aw3EM+.yxWEmkjspHtj6kYTk9Ks9xKhuN5tzp2uaLp80uNZdbmO7NaqNa1xh jE4YBhn0SJNc8m6s.jTlP7yMLi7NxhVsiGtjyG2UdUTg.4zlBw0WrJOOs8kV 2XwEwixRtMpJtJQQrX35WZxsR0zs9PJKs2TNuHOMs0qRckOriqrf2dNO9iIK ptokqwhqvu8jU0MAyViQKRVFWV09bUQKKaelVi2pofVy9tsNuo9vaMDLvUfj lWYGciQXkDHQ4cJVppqo72VckQjluvtEQteWZbiqraM8Wz1EGC8x6vdvY0p. 082N9P5RtXlEDU4IDJTNrM0P3LBn3CEPQl.zCCEw8CJV9wnUVPQkcVeodwPO af3oQnTHL9PjIOlnoh3bRzCGnrL6U+yNE85FW5teViKTOIGREZGQdsseZsEc P.ASI9AQ7iMttYSAmp+XnzObTP2fBM7oW+w+F.4T2QDzQqDTxIADGD8DMfiq h9E.zpDoFKUVb8f1zsggSTAR4a0MrB6lBMOuiBXzhig8fBOWPBrZLBNCEriU erCFM130eZRVWN4J4Tw02MLUleWw7ZRqlu.s4ZtG3UIYqGDza2zsAfZci2jr XQ6AcnF81hU4btVSfXd+ROwpPHk7BgqOn82LoTLTA0fxbRRXuYTOGYTx8tuc ymmdRVX5zIRFMbHYx9HNMLnYWIYJYPQxHWDLFNj7NZv6flwNpn4zSyHmEMBG L3LxYYCriz7VJzQpYnD4qlbMpTgte+qPeGz+oU6H3mNu47NNqL5CwKdO+Kv8 o38QUUEIWcWkxtbyIE8gN2f1m6w8XBy1IQX3i20GcYZ9UQo5oAd8yti4k67M f3QcQCQdT2WzP3HckQQJ+RciIQiTlTwbtwi3QJOx7cmGIS0U3VCBts.2zo2B b+W4eDeSQojdv4dRbhZbsswgGwEFskTxoZsQqxWtLM1A1mPr2IAGLRUDP70A ziCLIiNVYRJwclbrF+YDD0cljLRYRbfm6LIZpZ3pFEpUPYzxECNhsb0UD87U 7+8E7+YBjTqkgFcTp45Jrdv9Shv5QFvZBXQ.ON.MJC6Hnw.PFQGdQslQ.X9U 2ZRMITYvSosjEXj0IiLV+aeoANWspw5HUzyLiiGgQpXH04.UDAebCTQq7BAF pXFO6LS3iKu3pezahTFCtQyFalr4TSQNvCBcXfDp.pzb5dfoGQKQsaoOUVi5 xFMxXT2pCIRmh5VuQk04tvCrkgaSpizZOGhC4of+JUfTvUFmRUVC2THl62b. lpwl7yc+66fNp8cHl.l.bCEJpn0oSWaQShNOPy.hNlLcBPvSB.gOJQ6RHp7Q wLdfBmHBHX6BHtfGX3DQ9.YW9f56f7g+DQ9.YW9vI7HXhHe.cvBSnC3AahHe .cv.iK3g2zIEwd4+701mFRLU5lV.xn+YOdfxPOEwTRVJQKu.0ZsQCGdYHV6F qmyQrwQNhYM+v7Tg7OLnQj+iNjLwYK4iIVn+WARDiee8.V6bVVk8iwXzt0I1 kdwC.NINlZSaOX1gXZ24RlLRZhrpUz0Hx9.f1IQpLtJZcMnwrvptuuNSULAo nSTm+G+d9sqmOsAxuOK8WAU2UjAxu9ZP0MwfUBa642UBjEAIaZXUAlpVvUu1 aFgY3gCyP2vw6UBfNsRoNkbiZgw.3k9TFLj5TFNFbDSwwW9xOC7m.+XTJ357 Bv28Me8KJmMbx53vlYcruMYn0iZe50U0T1i94H64Kp1gGhVba6oYuyw29jCI +bra8XUHI0yJR5MYQxGTt2FzpqsUOv8mxdfaxN7qx3WkCcfzjxpuD7lhjkKi K9A4PFufeH2T7qxVD+IveFrLNKtfqTcA3i2DmAh.ySSV8BPRo9g3WPMTSv7a 3tyEW9WrzFwTq9jZP5pPHwXN8dvIY9vz.tA466xDNZ5PZQqsfo7bmEZCBoCx R9.pmj0e8q95WA13Px2emMumP5v+rg6SHr0hSRvzRL0Dhx8mC7Rw7nAdUlMI Ukq5LXiwvCcrLaL9AQWRVctaSAHrvPkuaoqNKn+xb+eHNkSnbU7RSB.kMgWk sh2GpuyoeUB1nDjrCR9jdMm9a0inm5E9uJhtZaK2IWCPhgUmATA.86xZXKuJ Wc1Btlv44YYbrUUdceWF+RU2DUAVkWTcwEf3zxX9khiJ.Qoo.Yk3MQLUMaHC Q1bNO+NE+SrTYJjUEPcSmpXAHVdvNs36OL0BbRJRCtloq3gSg..6XVHKIYzf gjwipBDAdOJoECCL12UI4QW0g.wFLjruyzr+gUSWHPOUV+KGUAis9fdtD.H7 xws5yvvo.o3ndQ+AEE6rvz.Qu3Xzf4XzhIxUYCugS8QwYSPCGaPHWKRWnfgC M602zbuUeV1Nxb54Jzx1e9GwZzhwnY6ayKJ3r2KiprVTHzwzFB4aLM4dNn1b In17Ua+KLL74fZ64fZ6nLMR+G0hNrYdht.TJlEHwjDUDyQL.WTuHmCQh+VNY 5ym24LAgsL05LUvPGnRIKUHZJpJHcFibnmNSq9i4hx0rDr6wfO0VTtow7rFJ y5QldxwCFqyy5oInHss9B9pvWAppiW12KBNM097Ae3kpj2gViDCbXfxgkFkH ASv4AW4tMF6t2q7prWPJYfsr+L8x9G77x969x9egXU+ssh+AAxPEROTEUroX ZmO3v2ZW5T0IbnZ+6M2DKr2I7mHVbSkfHtAsH9ux.w72wckIeHFTDsHIGnpF GWHCwWgmL4Yxf7Ur7nh.AU72k0KorZWOMJawl695qk1Ay42WA2JaYR17X4Co tWkuLf2MiOhrrp2Mi6uCPP4huRt7Ik2G+IWjb80wEJJH8WAIYadKIBaze1ku K6e+8u4a9Rv+M9EEw.NOvu2ZQlWTBPeAUQwxWn3vNMJGZV1hpiRY8ngUUHHD 1+TrM2L9bt5M2vaCeGWahXlbJ4MobgJzeO.jkWEqbZh23I8ZRO1ixjkYQbQj q0sn0t6Jan3Mbe25chs8dvIjPTiAmnqtOlFbB5IzfS16nnhhjgeIkK2iqihJ 66fGOGEU6DKYdM1SYb.FmXBllhtZ4vmbz4dUpGq26rYF7bxhFXv+LOcwwOBq gO9wpd83UEwrtMW7IHMpJ8Zx22FpRXSYT01XlJ.T.0QDUYAxmXyMzGFf54zH mrOBJC.rWOI1RsKshzSHBoQtAXRZ0G9TUG.wYvjvBbCLYrmpfI1cvD5JX9j0 5DxEvjcoubr79tglDxSTqR7wz+4IHvW8U.hZprE4jubFogNJvFplmDl0rcl5 226KejG8IJcC7hOP3UmPkN.uzmxvK5vfWbsCqVgWh2SY3Et2vqNPOXNBugST z0krZgUm7OD7yI+ig4+f1bO08IS1+31FYst9Cxn6Qwdvm1+E6gSR5y351nIg L9Bge1vI0N1GRFO9HYx3ijoCCR10c9Se5AtiTxjwzBUU+pIpvGa2GEhVemOm qJGMRFAOrFN+fKIROazaMbPUrI42+MNr9QDknBMWsXn7n9lSw8DmphOhZNE+ HjbX2SmcGL5AJ7pmWSJVO6QJcPhidDXTWxaUF6.YTO4N8BgoVXQc6KC8nzh5 RFRwNvc1XBUWaNawnvGGF8n5v51LpdquPWCSzEUh1GoKeLL1kx5NAo+6.ScM Ss7GN6k7TWyVR1vIcgo38vkxwUVzFdf1vvpP8C5U2Gn9n9tKfi7I0+AwnjPZ SMdhiFpLJ8gwnjVLJY3xnDuGlnqeSaXxi5YFkvFcZUHtlxprAT4ofbx8mW6A fdY7UNzKOpmknPtNOdzATlaCcs+NaXQyNMr+vmyb6gVlaKaMZO44pD4dao.c 5be+wd.aNbxtT.1RS48a0ueK98Rr78hdH1nGZ+ROHazCoeoGnM5A0azimuCz CsUwNY.POCM7ANrnGRXuQOa8o5fdB5W5wV+che+RO1zO21ahSO8XS+Lo+rWP ntH+P5W5wp7CteoGqxOn9kdrJ+ze5Cwtn+wyu2re4D8fGVjCp+Hm.WPm9y5E 1Eqon9yaULyE7oGoGWzNi6Oq6Xhq816Q5wl0Br+vBevCKxo+rc0tDA1E5XyW i44opx90aAvKQ9XDFyefKoAHFKT7WAHjOyS7WjFFtOdbAZRvEvIAW3.SziVy bYpEfCJxg1etd3hpn9abFnvof7OJXRvE9SBtfMI3BuIAW3hap8lpOWnFR+Mn BWHGDdXQNGpUS056rUgkUPIaUPY2pXxtcgjk+19iy++v423On -----------end_max5_patcher-----------
Good one. That looks like max to me. I think my solution might have converged on Chris’s latest — especially now that I’ve seen it — so I haven’t anything to add to the patching.
A few comments. First, I don’t think there was anything "wrong" with the original logic. It might be less idiomatic, but I don’t see a problem with it. Put your rope away. Second, I’m not entirely sure why max programmers avoid "if". It might have been inefficient, back in the day. Anyhow, if you want to program in this style, "gate" or "select" are more common. Third, we used to do these games at workshops I taught. Experienced programmers will solve problems differently. It’s part of the charm of Max, although it makes it harder to learn.
Amazing. Yeah, I guess that’s what I was talking about when I used the term "elegant". I’m also guessing this was a trivial exercise for you. It took me about 20 minutes of concentration to figure out exactly how/why your patch works. It works as well as it does, with as few components as it does because it makes HEAVY use of the right to left execution order, correct? That’s where my deficiency is right now, I’m not leveraging that concept much in my own code(except w/ triggers), because that concept is completely alien to any preconceived notions I have re: programming….
But back to the original question, how long were you working w/ Max before you reached the point where solutions like this started to become "obvious" to you? What was your prior background?
I posted the last reply before I refreshed & saw yours. Thanks for all your help/props, really does make me feel a little better. But your & Chris’ approach is what I’m shooting for, and I guess what I suspected my code "could be".
One thing I’m noticing, and of course this could just as easily apply to function overloading, etc. in traditional languages, and it is this:
The more concisely a patcher is coded, or the higher the level of abstraction (if that’s the right terminology…), the more difficult it is to look at it and figure out the entirety of what it’s doing. Of course that could be a noob thing. But I find even with my own code, the earliest revisions are pretty easy for me to reverse-engineer without any comments. But as the code becomes revised, more streamlined, tight, & efficient, I find that without liberal comments, I have no idea what the hell I was thinking when I wrote it, even a few months ago. So now I comment the daylights out of everything. Minutes of extra work now to save hours later. What a drag it is getting old…
One of the coolest things about Max is the ability to attach comments (bubble tool tips) to your inlets/outlets, as well as the Clue window, which allows me to have extensive commenting on my structures/algorithms, without taking up precious patcher real estate. One of the things at this stage that slows me down is having to navigate into patchers/between windows to retrace program flow. In that regard, the tooltip help is a huge timesaver for those "what does that do again?" moments. And it took me two weeks before I even knew that functionality existed. Did I mention Max is deep? And I’ve barely knicked the peel…
I got into Max in 1994, when all it could do was MIDI. (Chris was way ahead of me.) It was running on Mac LC’s, and efficiency was a big deal. Floating point processing was software emulated. A metro interval of less than 20 ms crashed Max. It tended to focus problems.
My background was primarily as a musician. Although, I grew up programming in BASIC and Lisp. I think I was lucky: I had enough programming knowledge to get the concepts but not so much that it made Max more difficult.
My programming took a major step forward when I started working CNMAT (UC Berkeley) and wrote a lot of patches for other people. Something that was "good enough" in my individual work was inadequate for sharing. And, we thought a lot about best practices when generating the CNMAT MMJ Depot. (It’s downloadable, at cnmat.berkeley.edu/downloads). So, I really needed a full-time job to get to where I’m at.
If anything, I would recommend *not* getting too involved in the aesthetics of programming. Max is great for artwork: one-off’s and prototyping. When I started, I was a musician and made some cool patches that did what I wanted most of the time. Now, I’m a server-side software engineer and I don’t make music at all. Programming can be a trap.
TLM_CBM make approximately zero use of R2L ordering; it’s all explicit using the trigger objects. It does make use of a data-flow mindset though, I think. Instead of thinking "I need to perform these actions" I think more along the lines of "the data needs to perform these actions." It is a mindset shift, but not really different in magnitude to the shift required to go from a standard block-structured language like C, to an object oriented language like C++.
The [if] object is a late comer to Max, and did have some efficiency issues, but those are mostly historical. Any inefficiency in your use of [if] is in the fact that there are four of them chewing on data that they mostly ignored other than redundantly turning off leds. Your use of [router] requires a slightly more complicated control structure over something like [gate 4]. That said, I agree with mzed that there’s nothing inherently wrong with your approach. If it seems clearer to you, it’s probably better for you.
Where I disagree with mzed is in "‘not’ getting too involved in the aesthetics of programming." For a quick and dirty one-off he’s right, but if you are making a patch that you think that you’re going to have to live with for a while, it should be as clean & clear as possible. In C code, this usually involves shorter routines, with well thought out interfaces. In Max it’s almost the same, good abstractions / encapsulations with well thought out data flow.
As far as my background goes,when getting into this world, I started out with modular synthesizers, and analog circuit design, quickly realized that I was way more comfortable with digital design, eventually including microprocessors (in assembly) as they got ubiquitous enough to use. I "graduated" to some "real" jobs, using Forth, Pascal, C, and eventually Object Pascal and C++. I started out with Max in the late 1980s, before it was a commercial product. In fact my learning C was because I wanted to write Max externals. Some of my early C efforts have been inflicted upon the Max community for decades, their quirks and foibles so cooked into the objects that they haven’t been changed for fear of breaking compatibility. Sorry.
My favorite programming adage: "You can write bad Fortran in any language." I look back on some of my early C efforts, and my reaction is "It must have seemed like a good idea at the time." I predict that once you more fully wrap your head around Max you will look back on some of your earlier efforts and wonder what you were thinking at the time. I know I have. I had a bias against lists for the longest time. It just seemed inefficient to pack/unpack all over the place. What was I thinking?
Here it is again. TLM_CBM has a few more comments.
----------begin_max5_patcher---------- 3958.3oc6cs2ababD+uk9Tr3RPcebVcewWFH+QqSRgAra.ZbSApUfAu6nNwX JxCj7rcRP.52g9MreR59hmHOcb28NcGEIkLfkDeOyuc1Ylc2Yl8WO+rIyx9b TwDvK.uCb1Y+54mcl3T7Sbl53ylbS3mmmDVHtsIyyt4lnzxISkWqL5ykhyWl GN+CfnzvYIQfEgkgU2wpvx4WGmt784QyKkeILlbgyT.gdAbJ.gb4+Bit.B9Q 0yDuP7Nyl8SOm5T8htJKsLM7lHwk9gn7Egoa9HoquIacYRTofHg0dhh3eQ7D H7EaNc9xYhaayYXOdbZ0Si3m62N+b9OldOQkYIwoe.LOIa9GzfGTO3s3gGUK bPGBvQRzBMrqS.+SAHAxFdX0O2E+Rb1MOg175yYXPYT96khd04W4sW9yqhje 2IwrVnMejSMS5hrmIcGpLIAaOS5MTYRHwdlzu2xjoQehQg2QCUN6yFAP.Lf. nVfBNhegHNZggfcpk5ujGGlra.xoMPXxzs9+luWKpyZ.TNGOfZUNq8.byunW VQJdPPdBU4NZUkCO5pxu2BIyVWVlkpkA83lpv99l6LPQ56Lbm15YgoKOhR72 DUTDtL5NsjT.TGGRcpwgNBNDEzBGh2+lvV498SxFeDkrAu80u48u4e+Mes49 +XZ.+W9Z6963suc+OVfRc5OJWAEJrf8JhSh9XTdQLSD+1O5YSBWsp1oOq1iv AveJS7hbmt4TwoxSA2bp7nOFW87dxSxZVNu5hUfnmmvFBBKLa5REBWT+ZvHq IbI2awnE0+.SxVEkFmtJOpf4kYXo5Ks4xKhtJbcR462MF075WENOp0GdmsUm MYYd7hrTNQz3I4mt5y8N.RHSv+4sLi3NRCWsiGtfwGqKlElyQNkoPb0EKyxR ZdoMMVLQ7vz3aBKiJikDKFt4kFeiPMciOjzR60EyyyRRZ7pjW4i63JKXsmyi 9T7hxqa3ZL+JraOdUUSvjMXzh3kQEkMOWY3xhlmow3spKnUuuaiyqqO7VCAC LCDW+J6naLBKk.IRuSwBUc0k+1pqLhT+E1tHxc6RiqckcqoeZSWbzzKuE6Am UoBT0e63CoKYhYFPTomPn.wv1jCgSKfhOT.EoCPOLTD2MnXwmBWY.Ek1Y8D5 ECbLAhmFgRtv38Ql7XhlRhyJQOruzxrS0OaUzqcbo89Y0tP0jbHTncD40l9o 0TzAA3LE+GD9Ot00MSJ3j8GCD9gi7aGTnAO95O9m.Hq5NhfVZkfRNIfXunmn FbbU3G.PiRjJrTZw0AZR2FFNREHEuU6vJrcJzbbNJfQCNF1AJ7rAIvxwHXMT 3dr5icvnwsd8mDm1lStBNke8cCSEYqymWQZU7EnIWy7.uLNcyffd2sca.nF2 30wKVzbPGxQusXUFiqUDHl0uzguJDBIu.3lCZ9MiK3CUPNnLqjD1aF0wRFkb m6a274omj4lNshjQ8GRlrOhS8CZ1VRlR5UjLxFAi9CIuiF7VnYrkJZN8zLxZ QifdCNirV1.aIMukBcjbFJQdxIWiJTn608Jz2A8eZ0NB9wyqOuiSJB+Xzh2y 9BLeJdeXYYd7r0kR6x0mTz66bCZdtG2iILamDglOdaezkIYyBSTSC7lmcGyK 242BhG0EMD4PseQCgCzUFEI8K0NlDMPYRIyYGOhGn7nqm87HYrtB2JPvtE3l N9Vf6+H6i3oKJkTCN2QfSTsqsMN3HtvnMjRNUqMZY1xkIQVv9Dh4NIX+Aph. hmJfdrfIcoCUljRrmIGpweFAQsmIICTlD66XOShFqFtpPgJETZsb4BGvVtZK hd9J1+dN6e5.I4ZYnPGoZt1BqGr2nHrdDArFGV3viEPizvNBpM.jQz9WTqoE .lO6FcpIgRCdRskt9ZYcx.i0+1WpgykqZrJREczy33AXjJFPsNPEQvG1.UzH uPfARlwwLyD7vxK15G8sQJiF2ncGZlrYTSdFvABsXfDx.pTe5dfoGQKQMaoO UViZyFMRaT2pBIRqh5VmAk041vCrggaSphzZGKhC4wf+JkfDvLsSopaM2TH5 62b.lpw57yc+66fNp8cH5.FebMEJxn0oUWaQihNOP8.hJlLsBPviB.gMJQyR Hx7QQOdfBFIBHXyBH1fGX3HQ9.YV9f5Yg7g2HQ9.YV9vJ7vejHe.svBSfE3g 6HQ9.ZgAFavCmwSJh8x+5aLOMjXpvMMejV+yd3.kddJh4C8TwshXvgH4ZsEz +xPrlMVOkiX8nbDqY0nnYO4WkBxxWDk+hKS+GfmCJhJAxhTwGCSldY5qYmiO VGPYF6ZoK.wkfOEWdMX9577H9zodcXZZTinPmGTTyyVKgTp9vZVkqJRgbkZT WmCJ+y1R.TeRsnIf2uS8u3zlsYV237+9O+WYSQVBqYHcQzmmxaUJWmmxaUxt 5pKSei3t3Mhrlu0QfqiWdMuQTd1zMOWH6O4wCF+AuJKGjx9h.QeiCrcjPcq0 Ph87M1PhdL0PJUbYJUk7jq6hTWuzYy5FLaalcOcHXcyG0mwxZjIT8iloSR+A 4EB7lxsBu5bjLZ.zA7tiMQWM4zjoDHlfk4DFzuVpggNjT0zH1MnyMrRPLeBd 2LilsJK5HFDAVBq20q417b9.vShkI+51S2YeLwrsIW2wv5Pq4t436A1NJx18 UgaJSYFDWUc+UYynNLEch5++v24Wq8etuVkWGAVwG1W15hJGwJx.eJBLOLst ebV3NF1TlfWuYA4KiYY2CJKSGn1zrJi4qDe8gW3QcgATqxad+iXhy+xW9Efe G3GBSD9g+5u4qeVwjdSsrPowrpXVXzizMSF73q2sthRvWhLlz2UtIQTxaau5 ssNsoO5PxuDaYeVITRcLBkNiVn7dUSGT3XUmaidt6Ml8bW+rvvtJC6.IwEku .7173kKix+dwP5mxNj4kzq3VyA+dvxnznbld0EfOccTJHDLOId0y.wEpGhcA 4TAHl2rkQE+ASMRp3ZHP5dE1X0h3fKeICtQltNk6epEEbCLyKHeDlunLXYXc FXBFo8xBJTWMmIu4Ue8q.25Xx2s1naT9zsciRA05.Y+wknpNDk4WG3k7UoA7 pTCXIMP3ofKr13+gVVDmF9fnUkBkM8mwd1UMTb86tBCy2GkvnTlhdggAfzxv qRWw5D0w3D008VIIyfjGoSKYLM5RzQcC+a4gy119c7U.Den4o.Y90bYZMK5k YxylyTENOKkM.7RY0a+xT9RubcXIXUVd4zofnjB133ShByAgIIx0PKlOMOsL .dhox8inpypZ6jEiF9JBzpceu9odfSRQ.xy15bAe7nGRQ.h54HKSDRGEHtaN piKZDd1VdZ5M0yCtpV6pAI8mh.jkUfDudEEas7+vppEgb6Ok.HaqXKXT+hlQ 1Ry8ixVzNfuVjMb5O37dTc1P8FJFOnpmbCwteCudeHq8wn+3jAx1p.Ixu+Py NcMM2YE.rsC8yNtDfs8m+ArHfoMbo+1r7bF68xvRiUcHUPSiPdZyC6mhZ5Vh ZZYl7fjAjumb+EyECeJpoeJpoOJSjz+Tt1C2NSQ7H4HubJeZhxiXHFfIpmmw fH9eKlO84yOzf4.4Jy1FeYN+5KyBIhlXrC83Yl0eHWbt56wGNtvGaqM23XlV CDoUuqZ5w8GpSz5oIlJMF3zx.YAJC9eya1MmlMWidezoJk2glCIi.eoCK0pA O5fyCdqgPan+dm520dAojd1p+KWreD0+oU929U9eJeg+MktJ99hPFRMTEYHp naq04v26vZU0IruZ+6sWGws2w8mHheSEfPlAsP1uRAQr2w5h3OFAxCWDmAjk 6oohH.l6ISVpHTg4KPJOlP4+cQ0hJK2Vs4ou0l69pqD1AyX2WNyJaQb5bYrF KuWouLfKmvFQVZ4kSX96.3TN+qjIdRw8wdxEwWcUTtjBR9YPb5suEQzJ+EWb Y5e+6d627Bv+J5Y4Q.FOvt2JQlmU.POmJoXwKjeXqFkCLrz0xRPGVMZXYInC g8NE6iZCOmqd60r1vKYZS3yjSAqIkITg9y9fzrxHoSSrFOgWSpwdTDuLMjIh bkpEsxcWQCEqg60a1pO2+HMWFtJpAmnJeb5FbB5QzfS16.ohhDggIkI2iqBj JyaQTOEHU6N7WbpsokYALNxDL0Em0hgOYoy8xjxVNJWjlTHgZPCL3ulkr33G p0vG9nVuZ7p7nW2jK9DjBUEdM44YBUItiYT0zXlxAT.0RDUZAxiXxMz6Gf5X 0HmLOBJM.rSGI1RMKshTSHBoVNBnSZ0C9XUG.wZvj35aGX559XELw1ClPaAy GsVmP1.ltW3IFKumcnIg7H0pDaL8eYLB7UeEfHmJadN8KlQZnkBrAx4Iw0Xp RS855M9UxCe0lXC7hOP3UkZkV.uzGyvK5vfWbkCqFgWhyiY3Et2vqJPObsDd CFonqM40haU5+PvOk9OZl+CZ8Ms8GM4+iU08Ahp.25R2i59fGs6q6Cmj7mw1 8oYR+IVfsNkeb6MAV6dQx3gGISFdjLsePx1t0R6QOvs7XWQLsPcTk8Gottcd T.Zyc1wo11.LQwrljQvCqgyy+BhvyF0dOJTFaRdceiia2HhRjglqRLTbTWyo 3NhSkwGQEmh69bI8t5ragQOPgW07ZRwpYORpChezC.iZSlN45dfLpiXqDi3J WXQU6qK5AoE0lrMxEefLJUUaOavnvGFF8n5v51LpZuURsGopJqDMOhnl2N2K DUdBR22AlZalZYcO3NflsMUkc6O48KEuGtTNrRg8fCzFFVFpePmp9.UG00cA rjOod2KFkDPqqwieTekQo2OFkzfQI8WFk3b+Dc8paCSbTGynD2AmVEhsorpa +I0fIjSt+7JO.TKiuzgdwQcrDEx14wi1ixbans82c6WzrUC6O3oL2tuk41hV ilSdtLQt2VJPkN22crGv5CmrMEfMzTd2V861hemDKeunGhI5g1szCxD8P5V5 AZhdPcF833YA8PaT3P5AzSeCef8K5gDzYzyVepVnG+tkdL0em30sziI8yM8l 3zSOlzOS5N6EDpMxOjtkdLJ+f6V5wn7CpaoGixOcm9PrM5eb75L6WVQO39E4 f5Nxw2Fzo6rdgswZJp67VE6ZC9zgziMZmwcm0cLw1d6cH8XxZA1qegO39E4z c1tZVh.aCcL4qw7rDYY+5c.3EHOLBi4awjTejqa.+u7QHOWG9eQpY393wEnQ AW.GEbgELQGZMyloV.1qHGZ245gMph5twYfBFCx+H+QAW3MJ3B2QAW3LJ3Ba bSsyT8YC0P5tAUXC4fv8Kx4PsZJWemsJrrbJYqBJ6VES1sKjrr21uc9+GdQt W4A -----------end_max5_patcher-----------
"make approximately zero use of R2L ordering; it’s all explicit using the trigger objects."
and why would you not call this r2l ordering?
When I think of R2L ordering in a Max patch, I think of the way Max evaluates thing based on where they are in the patch. Trigger allows you to control the order explicitly, not based on location.
The forum doesn’t let me quote in line, so I’ll try to keep this coherent and respond to everybody…
re: right to left order, I should have been more specific, what I was mostly referring to was the "t i 127 b" and the total reliance of the patch on the "firing order" of the outputs, and that you had strategically placed the bang on the right, I usually see them on the left in many patches.
mzed: Like you, music was first for me, and led me computers as a means to that end. There’s a lot of wisdom in your advice to to not get carried away with the coding, since as you correctly state, it can become a major time vampire/diversion, if the goal, after all, is to make music. It’s a little sad to hear you’ve been swayed that far from music these days… Great work on the CNMAT stuff, I scarfed it all up and will peruse joyfully as time permits. I’m in the "kid in a candy store" phase with all the freely available Max stuff on the web.
Chris: Object Pascal, Forth, Lisp, Fortran… Them were some heady days, no? I still have a TRS80 Model III in the attic, and somewhere I have the 5 1/4" floppies w/ some of my Fortran college course assignments. The landscape has certainly changed. I do share your opinion that if code/module reuse is even a remote possibility, then it pays to keep maintainability/readability paramount as soon as practicable in the process. I have decades of spaghetti code & rat’s nest wiring because I wasn’t concerned about reusing things, believing my brain and my time were a bottomless resource. Like mzed says, though, there’s a fine line between being a musician who programs and a programmer who plays music, but it’s a line I want to stay on the musician side of. Of course that’s just a personal choice, probably a dopey "identity" thing, not a value judgment in any way.
In any case, I feel pretty honored to have had my noobie code critiqued by a couple of the real "old dogs" :-) .You guys have my utmost respect and awe, having forged your signatures into the storied history of computers, music, & Max from nearly the beginning, when men were men & sheep were scared.. I don’t know where music is heading aesthetically. Frankly, I’m pretty disappointed with 99% of the current, mainstream use of music technology. Hey look, I’m really not an "elitist", honest I’m not… While I cop to a penchant for 70′s prog, I like most everything from the Monkees to the Eagles to Winger to Kraftwerk to Lawrence Welk to King Crimson, etc., etc.
But I gotta tell ya, if I hear one more vocals-quantized-to-half-step-auto-tuned-trance-gated-stacked-sawtooth-waved, well you get the picture. Just showing my age I guess.
I digress only to make the point that we have lived through some amazing times in the evolution of electronic music & computers. A close friend & mentor of mine worked at Bell Labs in Murray Hill, NJ in the 70′s. (I’m in NJ myself) He told tales back then of Hal Alles & Max Matthews, countless others. But me, being a 17 year-old long haired rock & roll guitarist, although being pretty good w/ my dad’s 100 watt Weller gun, a 5lb roll of acid-core plumbing solder, and a mad penchant for circuit bending, well I just didn’t absorb the significance of what was going on a half-hour drive away in the Lab’s expansive basement labyrinths at the time. Computers weren’t on my radar yet. I deeply regret that I did not seize the opportunity to meet some of the Thomas Edison’s of our day. The Labs was this incredible place back then where, brilliant, creative, eccentric people were given space, equipment, staff, & purchase order numbers, and their only obligation was essentially "to create", and that they did. I longed to work there someday, but by the time I was qualified, the gravy days were over. Like I said, heady times…
I guess that I didn’t think that "total reliance of the patch on the "firing order" " was much different than totally relying on the order of lines of C code.
That’s my point! It isn’t any different at all. You might have taken that comment in a totally different way than I intended. In text based languages (most of them, anyway) the implicit execution order, at least the main loop, is top down, even the function calls are generally executed "in order". What I was trying to say, is that in Max, "t i 127 b" , for example, is a somewhat different animal than "t bi 127 i" from the standpoint of any devices downstream. That, I think, is probably not immediately obvious to a lot of Max noobs. Yeah, we read the tutorials & sort of grok the right to left, top to bottom, deep to shallow concept, but I think it may be one of the later concepts to actually be really grasped/put to use.
I looked at your code, and considered it "more advanced" because you know to take advantage of that fact and use it to reduce the need for all the extra conditional checking, etc. that I was doing. I’m just starting to get to the point where I’m really trying to think about execution order. Until now I’ve been brute forcing a lot w/ various types of conditional thinking/checking. Your way is much more elegant. I certainly did not mean to imply that it was anything less than that, sorry if it came across that way.
I took no offense. In fact, I think we’re in violent agreement here. Procedural languages and data-flow languages are similar in many ways, just as procedural languages and object-oriented languages are similar in many ways. But… vive la différence.
I Say 4 Years!
Same as thinking in any language like English or Japanese:
1 year to learn the vocabulary, another year to brave talking to other people in it and consequently learn from the social discourse(this part being the most crucial), another year to seclude yourself in a bunch of high falutin pride over all the creative functions you’ve learned, and a final year to get humbled as you realize there is always so much more to learn before you feel like you’re really ‘thinking in Max’(at which point, you are actually ‘thinking in Max’; so it sounds like after just 3 weeks, you’ve already integrated the proper attitude).
"FLEEEEEE FOR YOUR LIIIIIIIIVES!" -Denethor II