Category Archives: max-lecturenotes

max max-lecturenotes

(max) presentation mode – syncRhythm

Up until now, we’ve been doing all our Max work in patcher view. Max offers another way to organize objects and present a clean interface to interact with your program, call presentation view.

I’ve made a short (12 minute) video lecture that demonstrates (right-click link to download). What follows is just a little summary/overview.

Download SyncRhythm-3.maxpat. It’s a variation of SyncRhythm, that allows you to synchronize note value changes to multiple metro objects. The differences are minor:

  • I’ve added another rhythmic metro (brining the total to 3). Selecting everything for one of the rhythmic metros and then option-dragging is the easiest way to duplicate parts of your patcher.
  • I’ve added comments above each tab object for clarity.
  • I’ve added number objects feeding each note number message, to allow you to change the MIDI note playback of each rhythmic metro, and comments for clarity.
  • I’ve added a comment above the global sync tab object for clarity.
  • To the transport section, I’ve added:
    • a metro object, set to a time interval of 1 ticks (has to be plural, no matter what the value), using the @interval attribute.
    • the metro object bangs the transport so that it reports location with single tick accuracy in the number boxes below.
    • the number boxes have been modified (in the inspector) to not draw the triangle and ignore mouse clicks, to display numbers only.
    • a comment has been added to the toggle for clarity.
    • and the rewind section has been changed so that clicking on the rewind message triggers a bang, first to a 0. value to rewind the transport, and then to the transport to report its updated location in the number boxes below.

SyncRhythm-3 is currently in patcher view. Along the bottom of the window is an icon that looks like a projector screen. Click it to go into presentation view. Your window should go blank, because nothing has been added to presentation view. Click the projector icon again, and make sure the patcher is unlocked (and in patcher view).

You have to specify which objects to include in presentation view. Select one or more of the tab objects, the choose “Add to Presentation” from the Object menu (or shift-cmd-p). Click anywhere else in the window and you will see that the formerly selected objects now have a pinkish halo around them. This pink halo shows that they will be included in the presentation view.

For my video demonstration I chose to add:

  • all the tab objects (for rhythmic metros and global sync metro) and their associated comments,
  • the number inputs and comments to change note playback number for each rhythmic metro,
  • the toggle and comment to start and stop the transport,
  • the rewind message object,
  • the floating point (flonum) object to enter a new tempo,
  • and the three number boxes and comments below the transport that display the current transport location.

I did not add any metro objects, the transport object, any of the message boxes feeding note value durations to metros, and the makenote/noteout objects.

While still unlocked, click on the presentation view icon again. Now you will only see the items you added to presentation view. Patch cords are not shown in presentation view. You can move objects around in presentation view, resize them, change their font sizes, colors, or most any other attribute through the inspector. Any changes made in presentation view do not show up in patcher view. Rearrange the objects, then switch back to patcher view. Switch again to presentation view.

Clicking on the toggle in presentation view starts the transport and all the metros. The patcher works exactly as it did in patcher view.

Download SynchRhythm-3presentation.maxpat. You can see how I have rearranged the objects from a full 1024 x 768 window into something about a third of the space. I have changed the font size of the rewind message so that it is more noticeable and easier to find. I’ve also added a comment by the tempo number box. I added that comment in presentation view. Try it in your patcher, position it as you want, then switch back to patcher view. The comment will stay in its presentation view location, as it has no patcher-associated location. You can add objects in either view, but adding objects in presentation view can make them hard to find in patcher view.

The final thing I did was to set the patcher to open in presentation view. With the patcher in presentation view and unlocked, go to the Patcher Inspector in the View menu (shift-cmd-I). This allows you to set attributes for the patcher, including whether to open the patcher in presentation view or not. Click the open in presentation view option, save your patcher, then reopen it. It will open in presentation view.

max max-lecturenotes

(max) midi learn and encapsulation

I’m using an example of how to program a MIDI CC learn function to illustrate patcher encapsulation in Max.

CC Learning

MIDI CC learn is a common function in most software synthesizers, whereby you want to assign an external MIDI CC to some software parameter by moving the desired external control (and not having to know or type in the CC number). It’s a handy feature, and one that we can recreate in Max.

Download ccListen.maxpat. The basic idea of the patcher is that you use one ctlin object without an argument in order to get input from all external CC’s. The CC # (sent from second outlet) flows to a ‘set $1′ message, that changes a second ctlin object to only listen to that CC #.

The programming issue is one of automation. You want to specify when to learn a CC # — when to listen — and automatically stop listening once an input has been received. That automation requires a gate, obviously, to turn listening on. To turn listening off, you use the first message through the gate to trigger a bang (any incoming message to a bang causes a ‘bang’ message to be sent). The bang is sent to the toggle, reversing its state and closing the gate. By order of operation, triggering the bang first and sending it to the toggle will close the gate after only one message (the integer representing the CC #) has passed through. After closing the gate, the one message that passed through will be sent to the set message, and on to the second ctlin object.

For additional functionality, I have an integer number object to allow for typing in a CC #. You could use this number object receiving a message from loadmess to initialize the setting. The rest of the patch just allows for some documentation, via the print window, and output of CC value and CC #.

Encapsulation

Encapsulation is the process of creating patchers within patchers. It can help to organize your overall patcher layout and function, and create shortcuts that you can reuse in multiple patchers. Download encapsulation.maxpat and ccAssignDemo14.maxpat to follow the presentation below.

The patcher object

Inserting a patcher (p) object creates a new patcher window. The new patcher window functions like any other patcher window, but it is part of the parent patcher. In a locked patcher, double-click the p contlassign object. The window that opens is very similar to the ccLearn patcher from the previous post. The difference is that contlassign has new objects: two inlet and two outlet objects.

Inlet objects within a patcher create object inlets. You use these to pass messages from the parent patcher to the subpatcher. Be sure to open the inlet inspector and add a helpful comment. Comments show up as popup help when you mouse over an inlet. The first inlet of contlassign is to send a bang to turn on the toggle and open the gate to set the CC number to the currently changing CC. The second inlet allows you to just send a number to set the CC #.

Outlets send messages from the subpatcher to the parent patcher. Be sure to comment them as well. The two outlets send the set CC value (the position or value of the controller) and the CC number.

Patcher objects are useful if you think you might want to edit the subpatcher from within the parent patcher. But the contents of the patcher object are only usable within the single parent patcher that the object is in.

Subpatchers as objects

You can save any patcher and then use it as an object within another patcher. Look at the bottom part of encapsulation. ccAssignDemo14 has the exact same contents as contlassign, and functions in the exact same way. But since ccAssignNew is a saved patcher, it can be used repeatedly in any patcher without having to type anything each time it is inserted.

The only small difference is that the inlets and outlets are not numbered. Their relative position is still important, and corresponds to their placement on the object.

Object subpatchers have to be stored in either the same folder as the parent patcher (the parent patchers has to be saved first for this to work), or in a folder that Max searches. If I plan on using an object in many patchers, I store the object patcher in Max/Cycling ’74/max-externals with the other Max objects.

max max-lecturenotes

(max) patcher dump 1

I’ve been focusing on cleaning up and commenting the example patchers I’ve been presenting in class, leaving less time to write blog posts about them. So, I’m listing them all here, with just a short annotation about each one. Download them, poke around, and read the comments – which serve as little mini blog posts.

>> Chord-coll.maxpat > coll object, symbols as data types

>> Chord-coll-2.maxpat > iter object, pack object, send and receive (s and r); shows how to take a list from coll and store it in a table

>> ChordPlayer.maxpat > incorporates Chord-coll-2 into RandomCounter.maxpat so that you can choose a chord from coll, store it in a table, and then play it back using counter or random objects sending index locations to the table.

>> NoteStoragePlay.maxpat > gate object (slightly different from ggate); replaces the chord-coll selecting and table storing mechanism from ChordPlayer with a way to store MIDI notes into a table from MIDI keyboard input, and then play them with counter or random objects.

>> NoteStoragePlay2.maxpat > midiin and midiout objects; same as NoteStoragePlay, except that all MIDI messages from external MIDI keyboard are also sent out to a software synth for playback. Double-click on midiout to choose an output MIDI destination.

>> NoteStoragePlay3.maxpat > modifies NoteStoragePlay2 so that MIDI through (via midiin and midiout) is disabled when recording MIDI notes to be stored in a table; uses a ggate to disconnect midiin to midiout whenever record toggle is on.

>> drunkExample.maxpat > drunk object; one type of weighted random distribution

>> TableSplit.maxpat > split object; weighted random distribution by storing multiple copies of data to increase likelihood of that data being chosen, and using split to introduce decision making based on range of data. In this patcher, split can introduce rests into the note playback stream.

>> TableCompare.maxpat > less than object (<); weighted random distribution; same audible effect as TableSplit, but uses a second random object feeding less than (<); result of less than determines if a bang will be sent to random object to trigger an index location being sent to table (and note playback). It’s a bit more direct in terms of specifying a value to < that represents the chance of note being played, instead of extending the range of a random object beyond the range that split is looking for.

>> Musical Time Lectures, part 1, part 2, and part 3 > video lectures describing how to use musical time (note values) and tempo in beats per minute in Max, with the transport and global transport.

>> MusicalTime.maxpat > transport, global transport, specifying time in note durations, tab object; example patcher used in Musical Time lectures

>> SyncRhythm.maxpat > loadbang and loadmess; demonstrates a global metro to synchronize duration changes in multiple metro objects, like in Ableton Live; shows how to use loadbang and loadmess to initialize data values when loading a patcher

 

max max-lecturenotes

(max) data types and symbols

I’m going to break down some of the topics covered in the last few classes. Hopefully these shorter posts will be informative and perhaps easier to sort and follow.

Data Types

Like most computer programming languages, Max handles a wide variety of data types, and different Max objects have different expectations for incoming data. We have dealt so far with integer and floating point numbers (representing two different data types), and symbols. Symbols can most easily be thought of as text and not numbers. In the first tutorial, you printed “hello world” to the Max window. The words “hello world” represent a symbol, or more specifically a list of symbols. Each word is separated by a space.

Eventually we will add audio as a data type. Although digital audio is simply a string of numbers, the rate and amount of numbers transmitted as audio far surpasses most control functions. Therefore, Max treats audio as its own data type.

Symbols

Some symbols are special, or reserved in Max for specific functions. “bang” is such a special symbol in Max, output by pressing a button, or sending the button any message in its inlet. Objects that react to bang are programmed to perform a special function when receiving bang.

At first, we will use symbols for specially formatted arguments, and to change object attributes.

max max-lecturenotes

(max) phase music using counter and modulo (%)

Using the counter object you can create a version of Steve Reich’s phase music. Reich’s phase pieces work by having two instruments play the same pattern. After a number of repetitions, one of the performers shifts their pattern relative to the other performer, creating a “phase” difference, or phasing. With each change in note offset you get a different interval combination pattern.

Implementing a phase piece in Max is fairly easy given the objects we already know. The only new object we need is the modulo object (%).

modulo (%)

Modulo is a math operation that takes a number, divides it by another number, and then outputs the remainder. The modulo sign is the %, and that is what is used in Max. Modulo is the same process used in counting pitch classes, which is a modulo 12 system. It you start with pitch class 2 (D) and add an octave (12), you end up with 14. In pitch class number terms it is still the number 2. 14/12 = 1, remainder 2.

phase music

(download ReichPhase.maxpat)

The basic elements of phase music is a pattern stored in itable, a counter,  two outputs from the counter, and an offset/modulo combination of objects. The itable has the first melodic pattern from Steve Reich’s Piano Phase stored as intervals.

One output from the counter goes directly to the itable. Consider this direct connection part 1. The second output from the counter goes to an addition object, which provides the offset for the second part. The output of the offset goes to the modulo object, so that the index number will wrap around and always stay within the index range of the table. This second output, offset, and modulo is part 2.

Change the offset amount in number of notes for part 2, and you have the same part played in a phase delayed relationship with itself.

max max-lecturenotes

(max) counter, key, ggate, gswitch, stripnote

Friday I modified the random note from table patcher to playback either in order or randomly. Along the way I introduced some new objects (and some that I’ve used before, but still need explaining). Before talking about the counter object, let’s make our way around the patcher and discuss some of the other objects.

(download the RandomCounter.maxpat)

key

The key object reports computer keys pressed as number codes. It can output platform specific codes, or ASCII (American Standard Code for Information Interchange) codes. ASCII codes are preferable, as they will allow your patchers to be platform independent — running the same way on Mac and Windows.

The select object is looking for the number 32, which is the ASCII code for the spacebar. When the spacebar is pressed, select finds the 32 and outputs a bang. Using key in this way allows for the spacebar to turn the toggle on and off (bangs reverse the state of a toggle object).

ggate and gswitch

Just below the select object is a graphic gate, ggate. Further down the patcher chain is a graphic switch, gswitch. I’ve put them side by side below (ggate on left, gswitch on right.

ggategswitch

 

Both objects have a control inlet as the left-most inlet. The control inlet can be used to change the routing of the object. Clicking on the objects has the same effect (changing the routing).

The ggate routes a single input to one of two outputs. The gswitch routes two inputs to one output.

stripnote

In earlier version of the random note patcher, note velocity turned the toggle on and off. But if you wanted to change base notes you had to lift up one MIDI note before pressing another, as any noteoff stops the patcher even if another MIDI note is being held down.

The stripnote object (lower right part of patcher) listens to midi note numbers and velocities, but only passes that data through if the velocity is non-zero. It strips note off messages from the data stream. The patcher now starts and stops with the spacebar, and transposes the itable output to the last MIDI key pressed. You don’t have to continue to hold the key.

A common mistake is to only connect the note input to stripnote. If you make this mistake, you will not get any output from stripnote, as you have to have a non-zero velocity to pass through data.

counter

Now we get to the part of the patcher that changes what we here. Previous versions of the patcher have played the notes in any order (randomly). Adding a counter object allows for playback of the stored intervals in order.

The counter object counts bangs. In its simplest form, you specify a minimum and maximum count as arguments, and the count will continuously loop from min to max. You can change the direction of the count, or have the count alternate up and down, with messages to the object. You can also change the min or max of the count.

The number box above the counter is changing both the range of the random object and the max of the counter. Since you specify the range of the random, but the output is 0 to 1 less than the range. Counter has to specify the actual boundaries of the range. In order to make the counter match to the output of the random object, you need to subtract 1 from the range argument.

Both counter and random are outputting index values to send to a table. Both outputs are connected to the inlet of the gswitch. Clicking on the gswitch changes between the counter (ordered output) and random output.

max max-lecturenotes

(max) patchers 5 and 6, rough versions

I don’t have time to add anything great to the presentation on tables from class, but I did want to link to the patchers. The rough version of 6 gives you some direction as to how to solve the changing chord/pattern problem for 6B.

http://ilocker.bsu.edu/users/kkothman/WORLD_SHARED/must342-14/demoPatchers14/ArpeggiatorPatcher5.maxpat

http://ilocker.bsu.edu/users/kkothman/WORLD_SHARED/must342-14/demoPatchers14/ArpeggiatorPatcher6rough.maxpat

max max-lecturenotes

(max) comparisons and the select object

The assignment for Patcher4 is a little tricky. Given what you learned in the first Max MIDI tutorial, you can see how a comparison object can be used to control a graphic gate. Comparison objects include == (is equal to), < (less than), > (greater than), != (is not equal to), <= (less than or equal to), and >= (greater than or equal to).

Comparison objects (Boolean objects) compare two values. Values coming in the left inlet are compared to the object’s arguments. If the comparison is true, the object outputs a 1; false comparisons output a 0.

To use a comparison object to route data you need to first perform the comparison, and then use the result of the comparison to control a gate that allows the data to pass through. Since the arrangement of objects in a patcher can affect execution order, it is important to control that order.

read more »

max max-lecturenotes

(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

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.

 

random12Range

 

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.

Offset

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.

 

offset

 

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

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.

Patcher3a-scale

 

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.

max max-lecturenotes

(max) keyboard shortcuts 1

Keyboard Shortcuts

You will greatly speed up your programing in Max if you learn the keyboard shortcuts for creating certain types of objects. (Keyboard shortcuts are money.)

  • Cmd-click (Cntl-C) on white space unlocks/locks a patcher
  • n creates a new object (at the current cursor location)
  • m creates a new message object
  • b creates a button (bang)
  • t creates a toggle
  • i creates an integer number box
  • f creates a floating-point number box
  • c creates a comment

Objects can be resized by dragging on their right edge. Clicking on their left edge brings up an info box about the object that you can use to set attributes.

Connecting and Selecting Objects and Patch Cords

Objects have inlets and outlets. Hovering the mouse over an inlet or outlet will bring up assistance that tells you the inlet/outlet function. You cannot connect outlets to inlets if the data type of the message is not one that the inlet will accept.

You can select objects in all the usual ways: mouse click, click and drag, shift-click to add to or remove from the selection, etc. To select patch cords you have to directly click on one, or option-drag the mouse over one or multiple patch cords.

If you start a patch cord connection but decide that you want to delete it without connecting it to another object, Cmd-click in white space to delete it.