note wrapping (cumulative transpose)

Danjel van Tijn's icon

Hi Guys,

I have been making a step sequencer with many of the features found on the Latron Notron.

Right now I am trying to implement a cumulative transpose:

If you set a cumulative transpose step to +3, then every bar the pitch transposition of the note at that step will increase by 3. e.g. +3 then +6 then +9 etc...keeps going up (or down with negative transposition)

In order for this to work you also need to set a note range limit with wraparound: (e.g. Upper note limit and lower note limit in octave multiples)
If a transposed note is above the upper note limit (e.g. it is 3 semitones above the max. octave) then it will be shifted down to 3 semitones above the lower note limit. (a shift of 1 or more octaves)
In this way, notes being transposed will continuously be rising upwards (with the exception of being dropped octave(s) when they reach their limit so they can keep going up or down).

I have been banging my head all weekend to make this work using max objects. The result has been spaghetti in order to get the message timing right but there are still bugs.

I am writing to see if anyone has any clever solutions for this?

The problem is that for each step, some sort of accumulator must keep track of the transposition state. (so that the original note pitch sequence is unchanged, you are just dynamically adding or subtracting numbers to it in order to transpose). There has to be logic in place to alter the accumulated transposition number so it acts as an octave shift up/down when the combined note and transposition value exceed the note range limits.
Can anyone think of an elegant solution for this?

thanks!

Danjel van Tijn's icon

I should add to this message that I am pretty new to max. I went through most of the tutorials so far and have been building this sequencer app as a way to reinforce my understanding.

I have past experience programming in other languages like C and assmebl code but have not been making javascript obkjects in max yet.I am doing this in an effort to try and limit myself to just max objects to get used to solving problems this way. However, this may be a good example of a situation where it is easier to describe the object function as a script rather than fiddling with too many max objects.

Also, one other solution I had was to dynamically create tables of all possible transposition values for each step based on current max/min octave and current step transposition value. A counter would index the position and look up the value to add to the current note/step being played.

dlurk's icon

Danjel van Tijn wrote:
> Hi Guys,
>
> I have been making a step sequencer with many of the features found on the Latron Notron.
>
> Right now I am trying to implement a cumulative transpose:
>
> If you set a cumulative transpose step to +3, then every bar the pitch transposition of the note at that step will increase by 3. e.g. +3 then +6 then +9 etc...keeps going up (or down with negative transposition)
>
> In order for this to work you also need to set a note range limit with wraparound: (e.g. Upper note limit and lower note limit in octave multiples)
> If a transposed note is above the upper note limit (e.g. it is 3 semitones above the max. octave) then it will be shifted down to 3 semitones above the lower note limit. (a shift of 1 or more octaves)
> In this way, notes being transposed will continuously be rising upwards (with the exception of being dropped octave(s) when they reach their limit so they can keep going up or down).
>
> I have been banging my head all weekend to make this work using max objects. The result has been spaghetti in order to get the message timing right but there are still bugs.
>
> I am writing to see if anyone has any clever solutions for this?
>
> The problem is that for each step, some sort of accumulator must keep track of the transposition state. (so that the original note pitch sequence is unchanged, you are just dynamically adding or subtracting numbers to it in order to transpose). There has to be logic in place to alter the accumulated transposition number so it acts as an octave shift up/down when the combined note and transposition value exceed the note range limits.
> Can anyone think of an elegant solution for this?
>
> thanks!
>

Danjel van Tijn's icon

Yeah I have seen the site before but unfortunately they do not have windows version yet. Also it's set of functions are not totally clear from looking at the screenshot. The site also notes that it is a keyboard centric application, but I personally prefer a mouse driven one with more visual feedback.
I had actually talked to one of the developers there a few months ago and he told me that they had plans to make a windows version. They may also be working on a hardware interface. Designing a custom hardware interface for my sequencer is also a primary goal. I decided to learn max as it would allow me to prototype and create the "brains" of systems very quickly. Then my hardware can be very dumb midi controllers.

dlurk's icon

>> numbers to it in order to transpose). There has to be logic in place
>> to alter the accumulated transposition number so it acts as an octave
>> shift up/down when the combined note and transposition value exceed
>> the note range limits.

I think you're essentially looking for modulo, aka the math object [%].
That should be the main component of your wrapping logic.

I don't think your goal should require any pasta unless I'm missing
something big about what you're trying to achieve. (Spaghetti code is
almost always unnecessary.) The classic advice is to use trigger when
timing is at all unclear.

Not near Max this evening so no demo, sorry.

Danjel van Tijn's icon

Since the transpose value is continually increasing (or decreasing) I could use modulo to determine the octave and offset however I would need some way to reset the accumulated transpose value.
I was using the accum object and then resetting the accum value by a negative amount equal to the noterange (difference between high and low note limits)
In this way the original sequenced notes remain unchanged and I am just adding a negative or positive value to it from the accumulator in order to place it within the noterange.

It just started to get messy with all the timing triggers and expressions. I should probably just re-write it however it may be easier for me to do with javascript.

cheers,
Danjel

Danjel van Tijn's icon

oops I don't think I was clear when talking about the increasing accumulated value. If I just keep letting it increase it is no problem to express a solution. However, this is poor programming to just let a counter increase without resetting it.
The complications in my current design are encountered when I go about resetting the counter but maintain the transposition direction.

dlurk's icon

I suppose you're far enough along that sharing the relevant portion of
your patch might do more good for you than a description. It's
difficult to figure out what "better" or "more elegant" might be without
a basis for comparison.

Danjel van Tijn wrote:
> Since the transpose value is continually increasing (or decreasing) I could use modulo to determine the octave and offset however I would need some way to reset the accumulated transpose value.
> I was using the accum object and then resetting the accum value by a negative amount equal to the noterange (difference between high and low note limits)
> In this way the original sequenced notes remain unchanged and I am just adding a negative or positive value to it from the accumulator in order to place it within the noterange.
>
> It just started to get messy with all the timing triggers and expressions. I should probably just re-write it however it may be easier for me to do with javascript.
>
> cheers,
> Danjel

Wetterberg's icon

Danjel van Tijn skrev:
> oops I don't think I was clear when talking about the increasing accumulated value. If I just keep letting it increase it is no problem to express a solution. However, this is poor programming to just let a counter increase without resetting it.
> The complications in my current design are encountered when I go about resetting the counter but maintain the transposition direction.
Why does this constitute poor programming? I mean, it's not as if the
process will tax your system - if it were audio-rate or really really
fast I might agree with you, but we're talking note data here.

Andreas. ("If it works, it works")

Danjel van Tijn's icon

ok what happens to an integer counter if it keeps getting bigger? Won't there be an issue when it reaches the maximum size an int can be in max?

Danjel van Tijn's icon

If an integer gets too high it will turn into a 2's compliment negative number and will effectively count down in the opposite direction. This happens when the counter is very high but it does happen. Theoretically it should be rare for me to leave a sequence going long enough that this should happen.