Look up chords in an array

Image

The coll object allows one to store an indexed collection of messages of any type. In this example, each stored message is a list of five numbers that will be used as pitches of a chord. (Double-click on the coll to view its contents.) The chords are chosen at random, but they have been composed such that they all have a valid function in C minor, and because they are all five-note jazz chords voiced in a similar manner and range, stylistically any one of the twelve chords sounds reasonable following any other.

The iter object breaks up each list into five separate int messages, each of which is packed together with the number 100 as a two-item list, and that list is passed to noteout as pitch and velocity information.

This patch demonstrates an effective way to provide note-off messages for MIDI notes. Pitch and velocity pairs can be passed through the flush object, and flush will memorize all pairs that are note-ons — that is, pairs in which the velocity is nonzero; then, when flush receives a bang, it outputs note-offs for each note-on that it has in memory that has not yet been followed by a note-off. In this patch, each time a list comes out of the coll, it triggers a bang to turn off the held notes of the previous chord before playing the next chord.

Sequential or random access of a lookup table

Image

One of the nice features of an array is that you can store data in a particular order, then recall it in that order simply by incrementing an index counter. Or you can access the data randomly, which still restricts your outcome to members of that data set but ignores the original order.

This patch demonstrates that with a 16-value array of pitches and another 16-value array of velocities. When you turn on the metro, originally both arrays are read in order, and each contains a distinctive pattern. Try clicking on the gGate objects to switch one or both of them over to random access of the table, to hear the effect of randomizing one musical parameter or both.

Refer to a lookup table remotely

You can temporarily change the name and contents of a table object with the refer message, referring to the contents of another named table. In this patch we use a toggle to switch between a major scale and a minor scale, triggering the necessary refer messages. Once we refer the table named “majorscale” to the table named “minorscale”, the tablenamed “majorscale” actually adopts the name and the contents of the table named “minorscale” as if it were its own (although the name that was typed in as an argument does not change). The major scale content does not disappear entirely, however. It’s still in Max’s memory, stored as a table with the name “majorscale”, so the table object can be restored to its original name and contents by the message refer majorscale.

The name that’s typed in as an argument also serves as the name of a text file that the table object will try to read when the patch is opened. If no such file is found, the table will be empty (all it values will be set to 0) or it will use the saved data if its embed attribute is set (its “Save Data With Patcher option was checked). In this example patch, the data of the two scales is embedded in the patcher file, but can also be stored in separate files named majorscale and minorscale.

The basic scale pattern of pitch classes then needs to be transposed my some number to put it in the desired key and register. The patch also includes a “legato factor” applied to the duration of the notes. The time between note onsets, also known as the “inter-onset interval” or “IOI”, is determined by the metro interval. That value is then multiplied by the legato factor to determine the actual duration, from attack to release, of each note. In this way, the duration of the notes is dependent on, but not identical to, the IOIs. A legato factor greater than 1 creates note overlap, while a legato factor less than 1 creates a détaché or staccato effect.

Table lookup

Image

The table object is what’s commonly called a “lookup table” or an “array”. You can store an ordered array of numbers, and then look up those numbers by referring to their “index” number (also sometimes called the “address”) in the array. In table, the index numbers start from 0, and each location in the array can hold an integer. In the table‘s Inspector, you can set it to save its contents as part of the patch, so that the stored numbers will always be there the next time you open the patch. When table receives an index number in its left inlet, it sends out the number that is stored at that index location.

In this patch, we use a table to store all the MIDI pitch numbers of the C harmonic minor scale from 36 to 96, and we use another table to store a shape — a drawn curve. (You can double click on the table objects to see their contents displayed graphically.)

To make a lookup table filled with a specific ordered set of integers, the table object is the best choice, and one way to fill it is to read in a text file that begins with the word “table” followed by a space separated list of the desired numbers. This example patch requires that you download the text file Charmonicminor.txt and save it with the correct name somewhere in the Max file search path.

You can use a lookup table to describe some curve or shape that’s not easily calculated mathematically, anything from a harmonic minor scale to a curve you draw freehand. Thetable object on the right has had a curve drawn into its graphic window, and its embed attribute has been set on, which has the same effect as choosing “Save Data With Patcher” in the object’s Inspector.