Hi, I’m new to max programming and working on some stuff for max for live. I find myself in need of a foreach loop to allow me to cycle through an enumerated type of variable size, is there a mechanism to do something like that in max?
perhaps [uzi], [zl iter] or [coll] dump?
From what you’re describing I’d say you should look into [zl iter]. Variable size doesn’t really matter here since zl will simply iterate through the list; no matter what size the individual objects are.
Thanks, I’ll mess with that today and see if it works for me.
As someone who actually came to "traditional"/OO programming by way of max, I would strongly caution you against trying to import traditional coding paradigms directly – this could lead to a lot of pain and suffering for you. For example, local variables are available but IMO deprecated. S (send) and R (recieve) are the MAX equivalent of global vars.
I can’t track it down right now, but I had a discussion on this subject awhile ago. Max is alot more like sysadmin than coding. Things may behave in unexpected ways, but they rarely crash/throw errors outright.
Thanks for the note jamesson, Max is definitely different to me, seems closer to designing logic circuits than writing code, but I think I can work with that, I’ve actually ramped up on it quicker than I expected, but I still find myself looking for things that aren’t there. Not really sure how things are going to progress, I’m just doing very simple things are this point.
It looks like [zl iter] is going to work well for me, but now I find myself in need of an object like [route], but which simply outputs the first number given to its first output, second number to second output, etc, for as many outputs as it has defined. Is there a way to do that?
Also I need to know how to create a patch which has a variable number of outs, obviously this is possible since there are built ins that do it.
Yes, logic circuits are another great analogy.
re par.2, I think you need [cycle]. Re par3, I don’t understand whay you need yet, please be more specific or better yet post code.
Ok thanks, I’ll take a look at [cycle].
For para3 I’m thinking that I want my patcher to have either 7 outs or 5 outs (most common cases). So you can understand better I’ll explain a bit of what I’m doing. I’m building a scale builder, inputs are: scale type, octave, key. Outputs are the notes of the scale, one on each output so they can be sent directly to pads, or hook directly into another patcher that I’m modifying in the current case. So for a standard scale there are 7 outputs one for each note, but I’m thinking for pentatonic scales that could drop to 5 outs. Of course I could just ignore the last 2 outputs, but I’m really asking for academic purpose as it seems to be this is possible since an object such as [route] has a number of outputs based on its parameters. Of course sometimes built in objects can do things that user created objects can’t, but if this is possible I would like to know how to do it.
Consider what will happen when you change the number of outlets. Any connections you made will get messed up. Better to build 7 outlets and simply not use them.
Ok thanks, I haven’t looked at using JS yet, I’m trying to learn to do everything I can with Max before starting to use JS with it. Since I already know JS I’m afraid if I start using that too soon then I won’t learn what Max can do so I want to get the basics of Max down first.
IMHO a mistake. By all means use js, there is enough there that’s max-specific to require plenty of learning on its own. Since you’re in m4l, I would suggest avoiding the liveapi object accessible through js and sending messages to live.object, live.path, and live.observer.
Thanks for the advice, I won’t wait too long before getting into JS, I’ve only been a Max programmer for less than a week so it’s ok.
[cycle] was exactly what I was looking for, code is much prettier now, thanks ;-)
Hmm, I don’t quite agree with your statement that send/receive are the equivalent of global variables. The better approach to that is the ‘value’ object; this can contain a value (as the name indicates) which can then be used (retrieved) throughout the entire patch. By merely using the same value object and sending a bang into it.
Also much easier to use than send/receive IMO.
@Jamesson I’m about to venture into JS world and am curious why you recommend not using the liveapi object and instead using live.object, observer and path? I’ve done a lot of coding with those three, which can become pretty cluttered, some of the js coding I’ve seen seems a lot more elegant – I’d be happy not to venture into js though, will save me a learning curve :-)
I’m not sure what you are trying to do with multiple outputs, changing in number, but you may get benefit out of Max style routing – I use it a lot.
Use one outlet out of your patch, but prepend the output signals with a meaningful word or number.
Let me explain through something I use a lot. When you have 6 fader values coming out of one patch, send them out through the same outlet but turn them into a list, eg messages will look like: 1 0.345 or 3 5.432 which are the levels of faders 1 and 3.
if they are different types of messages eg a clock signal, a fader value and a parameter name, you can use prepending as well
Messages then look like this: fader1 0.2341 or parametername "delay volume" or clock 2:45:10
each of these messages come out of the same patcher outlet. further down you use the route object to filter out what you need where.
What is wonderful about this method is that it scales very well: if you now need to add something in your abstraction, say a pushbutton signal, you just add messages pushbutton 1/0 it will not disturb your downstream patchers because they, through [route] only listen to specific messages, the first word (parametername, fader1, clock) being the key.
As long as you are careful with spaces in your keys you should be fine. Is that useful?
forward is your friend.
----------begin_max5_patcher---------- 822.3oc0XttaZCCFF92vUgUj1+XV1e97tG1UvzTU.baSE3fRbOrU0684XHsP GHRfPJ4G8P9vD+lm73XG+53QISyewVlf9A5WnQidc7nQwRUEFs43QIKSeY1h zxXyRVZKKSuylLY8m4su3i0oHntl6wkYtEVe7K.aJtJ0O69L2c2TXm4W2gBB CCbCyLAQUDrgvzjp+m.XR3ORLA86Me6aycdW5Rarq9YtKcVdcukMOVLe5Cem S2JB4O5qy.cS00k7+Ykcc.RR1oCJy9a7CLXRUw2FOt5WSNWv.HFGIjHkFYHs kQbsDq3RkTDHBmfofDHhyBRjuPHE5xo1h8BAZyf.2nwZEiPkSBBTjA5Vy.ld +L3iaDEgyg2Vbi0kNcQ7rQNDexb9jInjoot65TTYeND0+SmJPAtH1KAIMjfR AlHYZNaBRFLJMgQUmFFMCOUhxwRtTKnckJIG1pDu0pz1Dr6TI0fSkXb.K3RC S1UpDeXqRr1pR6PvtSkDCNUBBK+gyUDnydpDLrUInspzNDr6TI1fSknA8gE. gA5JUhNrUIZaUocHXmoRvW5Zk1OetMu34zh4sdMTJCVKjBRPqXZFN7xaBVEr zmnhAGX43jKM.JWUDLxaQkV27JW4aY0MYQlyNK+QmeaUuo.RvoXoQYXAUgAA XAJpJ9lswAggJslPhqO6wixPSau6nd2c.gH9L60dzo5NGYQSewOBJ5PG3o3h lYPfQfAoLrLo2MnSgSGXpL9Q3T8OUGd4wUl+DdktsUJPgk.PhC7NURAWii0V fHmEXHLrjHgnDooXJmZL5SiOzVNh6BnOGZy1.FRap1rMtHH.ggKsd+1HevLZ fYLllnomy9sAWh8aK1j3jTeZyaiWRU02Edk4OVLqtCp2pTzGWJysk9LWpOK2 sUifcaz8YymacaOw77rxpk7EuX2+swFmGx0Udp1ZqilmpsQruxipI4Q1e4Qz j7v6u7vZRdfdKOPi7m9ymAdSFe0e9LHtxxSS7mOE5K98K5wxCq+xCzD9zei2 iSEzH9.8WdNJe5wm+bQmOc8xORWs5IaQ4lyYLJgUo8PdQ0gxIwCybqOLdFSJ rOkU2d83py1ai+mzHfOy -----------end_max5_patcher-----------
not to forget listfunnel, and the message box capability to send things to receives.
----------begin_max5_patcher---------- 812.3oc2XtsiaBCDF95jmBKzJ0VIJxmv.sW0Gf9DzVsh.NIdKwNBb1Cc09tW aSHIzkjE1FkDkaBwCFO+7wOCL773QdSTOxq7.eA7CvnQOOdzHWHafQqGOxaQ 5iYEoUto4koVrfK0d906SyeT6hKUZNPOOUClpJA2fJ4Y9lw75+BxTxrTMWlp EJIPIKdBLOc4RtrBLgmktpxNQfnBLUTVoAezbLlwOnVUjK+f1L264lQk+lm+ olTWHj7L0JoK+j0Ampj5Jwe31XHb.bcX4pEBYAW6NGPaCpVoah1L0ko5r4B4 raMRPWSFbTbPbHKDx7A3vHypZ1DZ2PMC.+Z8QJxcjPM4tOS81QOxzEN838sR QZwl8TNahKuAPafWFO19ieOuLrfWUkNi+pKCe8mk0.+FbmbBO.Ng6jSMzqNj 9ok7ZH44sADcgPHYKBYN1UCRBpaBhO.AOh7BAZknFjjbBHBNI.SSHI9.TRbP BjDCs+GZuZ.Pr8XrPcxkuqjoYpiJXv.BEDx.QwfD34hQFqYDkEwBsDIN.gYX X3aCI3QFRlykI7xA.gtKwf2GDD1Bp.uIoxYGjGTZ3FdPIIAwQDHMxbqDzgi3 twAI9P3XS1JM6PyKu0TjdRgaJumBSR9Clb9J6TIHzbZL.BBOh1nVXCZLMLRL k3CXv.TLjfhN.6RtRsRjHR.ixhCQCxJwtDrRzymUpE11wJQIGDaQWqtHHJHj xRHrA4hnWBtHxYzEsK15uKJ7J0EYeUHJMBhGVsH7kfKBe9bQsv1.erF4J0Jg LcUPLLIAOHqD5RvJgNeVoVXaXVI7Q+Mj5lOEhJ8zURIu.f9u8Y6kR1rz+FYM MuxfLbhgTQgGxfgOUssgIf3DaaazP.4b0ZKhrkQHCiHlVain9fX1g5ZC22t1 bGr6yZ7Oe4JmTrwaCtJ0pxrFg2jIvVMjyqzh5uL0tSB0ZRyE44b4t22kKprk Ax2ecf9pG5kldPWV5A2K8bxjismv2TN1ltOU5IpO5gc5zSXezC8zoGRezyoy +f6k+48d6Uc0wzkKumWVsdMcRw7.j6Tk1gLe2PgrdnqHuWI+dQy7MqmY0dY7 esO9RZM -----------end_max5_patcher-----------