(max) range, offset, and scaling

Generating musically useful data requires an understanding of the terms range, offset, and scaling. (In future posts I’ll cover related topics like mapping and selecting.) I’ll use Patcher 3 as the basis for my discussion. (download patcher3)

A patcher that plays random notes within an octave at a 
regular time interval, using input from a MIDI keyboard 
to set the base note of the octave, and to start and 
stop the playback of notes.


Range applies to the how and high boundaries of a set of possible values (data set), and also to the number of possible values within those low and high boundaries. In our example patcher, the instruction is to play notes within an octave, making the range equal an octave. Without any additional direction, once assumes that all pitches within the octave are possible, leading to the number of possible values being 12.

We implement the range in the patcher through the argument to the random object.




Random outputs a range of random numbers defined by its argument. Since computers start counting with zero (0), the low boundary is 0 and the high boundary is 11. Get used to starting your count with zero. Typically, the range is 0 to one less than the range argument.


An offset is an amount added (or subtracted) equally to all values in a range. In the example patcher, the offset is supplied by the midi note number, and applied by addition to the number output from random.




Offsets do not affect the size of the range (the distance from low to high boundary) or the number of steps within the range. In the example patcher, offset is applied to pitch, which in musical terms is transposition. Offset can be applied to any other parameter, such as a range of rhythmic values or a range of dynamic values.


Scaling is a multiplication process that changes the size of the range. I’ve made one change to the example patcher (Download Patcher3a), adding a dial to change the metro time and makenote duration arguments. Since a dial has a default range of 128 (0 – 127), it doesn’t have a great impact on changing durations specified in ms. To make the time change more dramatic we need to scale the output of the dial (in this case multiply each step output by 10 ms). An offset is also included to ensure that we don’t have any zero durations.



Max objects have attributes: properties that can be defined to change the behavior of the object. For user interface objects like dials and sliders, these attributes can be used to define the range, scale, and offset of output. I’ve added a second dial to the patcher. In the unlocked patcher, move the cursor to the left edge of the right dial object, choose object from the popup ring, and then inspector from the popup menu. (Or you can click on the dial object, then type Cmd-I)

objectring              objectInspector

The inspector shows that the dial has attributes for “Number of steps/ range,” “minimum value,” and “step multiplier.” Leave the range as is, but change minimum value to 50 (our offset from the output of the left dial), and the step multiplier to 10 (our scaling factor).

Each implementation has its own advantages and disadvantages. The part of the patcher dealing with the right dial is obviously more simple in appearance (fewer objects), which can be helpful. The visible multiplication and addition objects attached to the left dial allow for you to more easily see and change these parameters.


Leave a Reply