counting algorithmic problem
I am horrified to ask this.
I am trying to create an expanding interval series and use that to count my way around a certain pitch range either up or down using a counter.
So if we were going down we would define a top note to start on and a bottom note as a lower bound that we would go modulo around as if the keyboard was circular. We are counting keys like we are Tom Johnson or something.
So imagine our top note is A5 just above the treble staff and we want to wrap around at G3. We want to count down from that note a 1/2 step and we arrive at Ab. Now from Ab we count down a whole step to Gb. Now from Gb down a minor third (3steps) to Eb then 4 steps to B4, 5steps down to C and then 6 down to F etc. when we reach the last key we wrap around and keep counting from the top as if the last key and the first key were attached.
This isn’t exactly what i want but a vastly simplified version of the problem and i feel like if i can get this to work in both directions with a simple expanding series without a stack overflow or an "off by one" error, then I could add all the other fancy layers on to that. I have coded something like this up in C in like 10 minutes, for some reason the max part of my brain can’t see what is wrong. Must be some easier, more bulletproof way to do this than what i am doing. I have reduced it to it simplest form and it is still hosed.
I was "off by one" but now it seems to work only counting up. It gives a stack overflow in the other direction. Added to this is my feeble attempt to visualize the pattern in a histogram and also capture it as MIDI data. Surprisingly this part seems to work.
Try the pong object (Max 6.1 and up) for the wrapping. For flow control it’s more idiomatic to use gate and switch then if/then.
Wow! pong is awesome. It does a ton of the heavy lifting for me. I did not know it existed. But I can’t figure out how to make it go down & wrap.
----------begin_max5_patcher---------- 974.3oc0XsriaBCEccxWAxK5pzHrMuRW0J0EcQU20toZTED7jwi.CBLSloil +85GPdUBwARnoizXhMF6y8bOWeuvqSm.hxdlTBr9f0OslL40oSlnFRNvj59S .ogOuLIrTMM.qJMhT.lou08YLdI82D4sf3410CSiUyMK5w2Cc2ctrvT0bAep fFlzbm7vBw3bRwuHrvnD0LZVJw9kUwSHb01ipGUOD+kbhF6.JiClYAhBYq.V 2s8YorlGEtYy3KefxV8qBxRt9owHIzsv11pKNP4Ejn05N4y71zoxlYFxPQUb dFCzBUfAsZTviYTCxZfHs030z1KigQVKfdCt4jmUaBXYVEieNx.jyokA6yJN mvU27ura6bj6I4HjmxU6iGjCeYVZJQBpCHIAxrJEXwJlJ2Y5VQwo4Kr84xWM Kx8EqhT8ma2kvIpJpNRqCojCJXN12UHlBblGH+S9ajihtbu3wG1iS7guybWo 61cNt1jzgJx1Kp.PhOqx0TADH8SE3danBVniOPaHLnm+fz.maVDr++AYQbCl CQpfEuMAKtC6nkJgtpxbZxGeIoIbyFvIo00H.9dtjflIa9b1Z1lN5we2lw2v dcd78.3XmEa3XufqT9Z3nbdDzEoxW6nhxb8ZZ6kwjVkvokIz3sQW6XQt8OVI ufTJNiKTd.1dIRg5RmT4DrqaNt2ee2tL6H+E816tcLAuILJ8SXqqkwemE0Th EoyqiW.2odHnceOk+9jLwN2ZvHpsfwfViE+BI4IBmtLz5ajJh0Woqdfes7JH eOy7JBSKb.m70PzdpKt1CJb7HUblmIxkZagCr9XZVLwZcQXt49B7Y6KLLj+H jE9zjEVEw.00m2e153IRamH7ZkI9AoHNjEdqjJ0GoqN265om55MXZk4bFnD5 p99L0DFFeAdcFd1pUBW9ey.dmu7.1kQ2SYAzcQS05Cnl8iHKDlUQlLIg4BC+ q0YKcD6fNIIEnNdwyYPRgtql.AufmWLlEFnon+U0EfFiBCtzo3qora2L7nE2 No3qIqtyvqVUPBkc32eUsfxw2mBKypJV1folOol0VweLojSYpJA2YR38lyCz 3XBaW0SLsTJnT7ncq9RSgiuAnANdvAaBdTTHbTvyAldG3Yb3GiTOxOd+HgG4 G+6Vxe4ah+5.Q1UUOa.bBFOuEz.3Ldh4.CPi6M0IgiG23Y.ZFOYrQ4r7FunJ SXGYoEi0oxKLAOiWbNxjHKDrm3QWBTXd9Sjhx50TAEQ8hOlUH65MS0kxzcUE oAJHOQaludjvBQMXbQAXUE559d1yALUtOuM8OvMZoLB -----------end_max5_patcher-----------
What you’re describing sounds to me like a pretty straightforward application of modular arithmetic, using the % object. See if this is what you want. It goes upward initially, but to go downward you would just change the pitch offset value to your top pitch (93 in your case) and change the direction to down (-1).
----------begin_max5_patcher---------- 1014.3oc0YssaiaCD8Y6uBBAzWZcB3Ecs.8g9cTrXgrMiMWHQZHQsIsK1+8R MTxWRhknTr0p7Pr.onHm4LGd3vI+X4Bu0pW3kdn+D8OnEK9wxEKftp6XQS6E d4ourIKsDFl2FUdNWp8VYeml+hF5euX2ddoFcPn2rG8.JS87ol+Ahf9KjVoS yPxp707Bj5IjTo4kHgDo2yQEoxc71YMSH4aTURXpoMcdH0LUB4tuVv2nslLM H7Q7JD0Ot9AIgV+fwdDi9RyGYVMUkNiqAqG2zqXKXyp0e6Aeb6h9jRpko4b3 U+cgHM63aJ1sF97GwmM1Rw+AikPO1sY0Dx1EiT22OWtr9mUNhtR9yFi5MfqA +75.EvwmgBL5iAlF3qBBj2BBr31o2NN8+dfamaOQcP3K8CQN.HzQ.HWitUc. oJPaUOK6.XZHDI.IIBCfDdHjCVzbhbjyKKSOsI4HV7PmjCpOr2fPOQNHwChb vtJ43WIy3ZnAoeBwGALHyRv3J5F+dm5FjHXiAwGXHAjd1e7NnAMYtpabMgTG fiX+wJiRmsxnZ0tcY7NbdqFIIrkCLXWO5zjWXbMMu3qbY55L94RqcCKe7SOg TK5JDao5V2LnO2j9NtYfKtowMD4U40cEzkmuB4s1j1yshXbCS3v3YEJS5U3d oL9.JFFMBJy0OW4VhJ2xrNJ3kbsKYhAJHQCOgCJcNkvw5JsVI6WxzGOZYCri bf6VxS39CmV2aLYKPhmkYKzA8tJqK9MIFRRfk7pvt6DbR3r55V8dfgkfyhF8 IFD+AdhAdPmXXbm1OjPi5EZOTqfI0oZgRdgaZu5XLHYga94BF58.9uFOzVz. 0SO0mZqciIFjaCiGAaj7ohM1nGwrJsigMlLmHiSdQTBwNrUe72FJ5S1kgfJr 4h7WDbc4XVOPh+agjPudHPs+cCQnfa4Ih0UkDAqXu5PM6NCCGtNTvmQYnlJK MFYH1.kgHeNuE0uYTS5e2E0t8ZLJNjoVwAlRn77u5eZ.3d08eIJUppJ1zZSs kHAcxC2xK0BIjNxYChbwX1K1tkKOmYrUTVSV.b.+tgKmMmDGLmWYy2S6g3B7 XDUQzIwbBcAcRlLzg4J4gLMliCVCaB4NNXNQyJqA1X0UrJWr8fxHkU1d8y.n nrI1Jq7dOHQ1GIIGacxHtcQdhqaLlHlHadYONIiMznOkDUG8CCfvsMMqKZPB SNO1W25ND6oLGknwCfXiCZbMnDSGabOL+HWBMro6D3.Wsmog5VWQxOb381YN tDspKwzDYNINdFyXhU1bKSOb367hxloDLDSt1eSUT2Lb0R6ECrMgLh8J3eWz NdFzSZgIUasIO6pBaNuuDG5srdc94x+mpPmOE -----------end_max5_patcher-----------
Thank you Chris! It is indeed a % math problem and looking over what you have there I spy a few things I got horribly wrong and a few things that could have been done way more simply than the way I was trying to do it. My brain is on like .1 power so I probably should have let it go till i was stronger but it was kind of making me crazy. I will look at this more and go through it step buy step but already see several things, such as resetting and direction change that were just a mess in mine. Thanks for your help. (still curious to learn about pong)
(sorry for the late reply, just out of the hospital and i sleep like 18 hours a day)
when you continue using % you will often run into situation where it seems that it doesnt work right unless you add or shift for 1, but other than that, it is a pretty straightforward "wrap or loop thing". :)
Also, modulo doesn’t work the way you expect when dealing with negative numbers. -7 modulo 8 is -7, not 7. I use the following with modulo to deal with this:
+ 2*n // you could use n here, but I like 2n because it guarantees no sign weirdness (i.e. -0.)
That all said, we have pong now (as of Max 6.1), and it deals with the offsets, so that’s easiest to deal with.
My god this pong!
my "modulo" for "also below zero" is called 110.loopi:
expr ((($i1%$i2)+($i2)*(($i1%$i2)==0))*($i1>=0) + ((((($i1%$i2)+$i2)+(-$i2)*((($i1%$i2)==0))*($i1<0)))
this works for ranges with a base of 1, for example 1…10, 11…20, and -19…-9, you might want to add an additional offset when you want to reach a range of 3…10.
oh, and for the floating point vesion you must of course do the modulo by +-*/, as the % operator in expr wont work this way.