This tutorial is focused on data scaling and smoothing issues. It introduces the
iter object for list iterations, and the
trough,
peak and
slide objects for data scaling and smoothing. We will also look at additional data display options for the
multislider object – in particular, the ability to set a minimum and maximum range, and using the peak-hold monitoring in that object.
Different Max objects and physical devices produce values of different ranges and formats. One of the tasks that you will often perform is altering the incoming format and scale of a data-set to match the format and scale needed for your output. While earlier tutorials described using the
scale object for this function, we might need to employ other objects to find out the numerical range for our scaling first. The objects introduced in this tutorial offer new options for scaling, smoothing and viewing data to suit your programming needs.
Take a look at our tutorial patcher: on the left side of the patcher is an overview of a few new objects (outlined in green). The top-most patch shows the
iter object in use – it accepts a list, and outputs the individual values in order. When we click on the
message box, the four-value list is sent to
iter, which outputs four messages – each one containing one list item. This is the simplest way to turn a list into a data stream, and (as we will soon see) is useful for
atomizing the contents of a list in order to trigger a new event from each list element.
The next subpatch has examples of both the
trough and
peak objects. They serve complementary purposes: both object examine an incoming number stream, with
trough capturing (and outputting) the lowest value received thus far, while
peak captures and sends the highest value. When we change the value in the
number box, we see that the objects capture the low and high values, with new output occurring whenever a new high or low is reached.
Finally, the bottom subpatch shows three uses of the
slide object. The
slide object is used for
smoothing out data based on a “smoothing factor”, with separate factors for
upward and
downward movements. The function of the smoothing factor is rather simple – it is used to divide the difference between the last received message and the current one, thereby reducing the amount of “swing” in any value transition. The smoothing factors are provided as two arguments to the object: the first argument is the factor for upward movement, and the second argument is the factor for downward movement.
For example, when you first start the patch, the “last” value is
0.0. If you make an immediate transition to
0.5 (which you can do by entering a value into the
number box connected to the
slide objects), you will see that the first slider moves to
0.01. This is because there was an upward transition in value, so the first factor (
50.) was used: the difference between the initial value of
0.00 and
0.50 is
0.50; this difference is divided by the factor (
50.) to yield
0.01.
The three
slide objects show different smoothing factors: the first provides even factors for both upward and downward movement, the second has no upward smoothing (a factor of 1.0), and the third has a small downward factor (a factor of 10.0). As you move the input slider - actually a
multislider with only one slider set to have a floating-point range, you will see that each output
multislider responds differently – smoothing the output in relation to the upward and downward smoothing factors of each
slide object.
The main patch uses weather data as source material; it drives the display in our
multislider, and is also used to create four-note chords for playback on the computer’s internal MIDI synthesizer. Double-click the two
coll objects in the patch to become familiar with their contents - both contain twelve lines of data, where the output of one serves as the index of another. When you start the
metro (at the top of the patch) with the
toggle object, the
bang messages are used to generate calendar information – specifically, the output of a
counter (which is counting days) is used to query a small
coll database that outputs the months based on what days in the calendar year they start - e.g. day
90 of the year is the first day of month
4 (April). This month value (in the range
1 to
12) is then used to query the
coll loaded from the file
weather.txt, which contains the average monthly temperatures in four cities (New York, Paris, Buenos Aires, and Tokyo). This data is
unpacked (since it comes out of the
coll in the form of a list) and is sent to four
float objects. The
metro then bangs the
float objects to create a stream of output. This is a good technique for use in systems where you require something to happen on a regular clock but the incoming data is not produced at a constant speed - in our example, the list of temperatures only come out of the
coll object when the month changes.
The output of the
float objects are sent to
slide objects with a smoothing factor of
15.0 for both upward and downward movement. This means that, while the same value may be sent as many as 31 times (since there are up to 31 days in a month), the value will still change as the smoothed output catches up to the actual value. The output of the four
slide object are
packed together and sent into the
multislider, where they are displayed. This newly created dataset is also output from the
multislider, where it is split apart (by the
iter object) and used to make four notes for synthesizer playback.
This
multislider uses a few new techniques for data display. Open the object inspector for the
multislider, and you will see that the
Slider Style attribute is set to
Bar, which gives us the filled bar. The
Candycane option is also activated, so that the bars are colored based on the colors in the inspector. Finally, there is a
Peak Hold option set, which causes a small bar to be located at the top of the highest point that the value reaches. This gives us a visual indicator of the peak value seen for each of the four cities.
There is a
toggle connected to a
message box that can turn off or turn on the peak hold function; this is a good example of using inspector-type messages to control the function of an object. Since any change to the
peakhold attribute should reset the peak tracking, a companion message (
peakreset) resets that value any time the
toggle is changed.
The other part of this patch worth examining is the setup performed just to the left of the main patch. This patch section has a singular purpose: to set up the
multislider for proper display scaling. A
bang message (either sent by clicking the
button, or generated by a
loadbang) starts by setting the
trough and
peak objects with very high and very low thresholds, respectively - this guarantees that any new value sent to them will automatically set a new standard within the object. The
bang then triggers a
dump message to the
coll object, which causes
all of the entries to be sent from the object, one list at a time.
As the lists are output, they are processed by an
iter object, that splits the lists into single-value messages. These are examined by the
trough and
peak objects, which find the lowest and highest values in the data set (
32 and
81, respectively). When a value is found, it uses the
pak object to generate a value list,
prepends the message
setminmax to the list, and sends it to the
multislider. This changes the display range that will be shown, causing the
multislider to limit its display to the actual range of high and low temperature that will be output by the
coll. In this way, the
multislider display is automatically calibrated to the temperatures stored in the
weather.txt file.
In this tutorial we’ve seen how to analyze data streams (using
iter,
trough and
peak) and smooth their output (using
slide). We’ve also seen some programming patterns that can be useful for automatically setting up UI elements, and for outputting data when new data is sent less frequently than it is needed. Finally, we further explored the flexible
multislider object, using it for a bar display with peak hold values and full-color display.
See Also
Name |
Description |
iter |
Break a list up into a series of numbers
|
peak |
If a number is greater than previous numbers, output it
|
trough |
If a number is less than previous numbers, output it
|
slide |
Filter an input value logarithmically
|