Forums > MaxMSP

counting algorithmic problem


kp*
July 29, 2013 | 8:05 am

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.

Attachments:
  1. spiral.maxpat

July 29, 2013 | 9:04 am

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.



kp*
July 29, 2013 | 11:30 am

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.

<code>

– Pasted Max Patch, click to expand. –

</code>


July 29, 2013 | 11:40 am

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).

<code>

– Pasted Max Patch, click to expand. –

</code>



kp*
July 31, 2013 | 10:28 am

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)



kp*
July 31, 2013 | 10:29 am

(sorry for the late reply, just out of the hospital and i sleep like 18 hours a day)


July 31, 2013 | 3:10 pm

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". :)


July 31, 2013 | 7:01 pm

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:

% n
+ 2*n // you could use n here, but I like 2n because it guarantees no sign weirdness (i.e. -0.)
% n

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.


August 1, 2013 | 1:24 am

My god this pong!


August 1, 2013 | 5:51 am

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.

-110


August 1, 2013 | 6:02 am

oh, and for the floating point vesion you must of course do the modulo by +-*/, as the % operator in expr wont work this way.


Viewing 11 posts - 1 through 11 (of 11 total)