Category Archives: max

max max-lecturenotes

(max) theremin fun, part 1

To explore some basic audio functions a bit differently from the tutorials, and to explore ways to control parameters via the mouse and the lcd object, I’ve created a series of Theremin patchers:

The patchers get progressively more refined and functional, in an attempt to match the functionality of the online Theremin available through Femur Design. I’m going  the first two in this post.

ThereminFun

ThereminFun is a first, basic attempt to use the mouse to send frequency and amplitude information to a sawtooth oscillator. It uses mousestate to report X and Y position info for the mouse, and whether the left mouse button is pressed or not. Mousestate has to be polled (sent a bang) to report mouse information, which is being handled by a metro object.

Mouse X position is being scaled to frequency. Mouse Y information is being scaled to amplitude. Screen parameters of 1024×768 are being used. You will have to adjust the scale input to match your screen resolution for best results. Since frequency relates to pitch exponentially, as does amplitude to loudness, an exponential curve factor of 1.006 has been added as the fifth argument to each scale object.

You can see the frequency and amplitude information being sent to the basic audio signal chain of the basic audio patcher. Frequency and amplitude values are being inserted into a list and sent to line~ objects for smooth changes.

ThereminInProgress

ThereminInProgress takes the ThereminFun patcher and adds a selector~ object with four different oscillator waveforms. Selector~ works like an audio switch object, using control messages by number to select different inputs to pass through to the output.

The basic audio output uses a live.gain~ object to change gain and provide a meter display in one object. I like the Max For Live objects for their integration and labeling features. Live.gain~ expects amplitude settings to be communicated in dB, so amplitude scaling is changed from 0. – 1. values to decibels (-70. to -0.1). Since decibel maps linear values exponentially to amplitude, no exponential curve is needed in scale. Also, since live.gain~ has an internal ramp time (set in the inspector), a line~ object is not needed.

Likewise, we can map Mouse X location to MIDI note number to avoid the exponential curve. Using floating point output arguments for scale means that we will get a more continuous floating point MIDI note number than the standard MIDI spec. Not only are floating point MIDI note numbers ok in Max, they provides a continuous pitch scale beyond the confines of equal tempered tuning. The MIDI note number is sent to a mtof object (MIDI to frequency converter) before passing to the frequency input of all oscillators.

…to be continued

max max-lecturenotes

(max) a most basic audio patcher

To get started with audio processing, I’m first posting a most basic audio patcher: BasicAudio.maxpat

(I know that I started with the Theremin patcher, but let’s start with the most simple patcher.)

Basic Audio Patcher

The patcher is a simple sawtooth oscillator (saw~) with changeable frequency via a float object. The amplitude is controlled by a *~ object (audio multiply).

The BasicAudio.maxpat shows all the essential elements of audio synthesis/processing in Max. Audio signals travel on “bumble bee” patch cords. You need a dac~ or ezdac~ object to not only hear audio, but to turn on/off audio processing. Changing values to the frequency input of the oscillator (saw~) and the amplitude both are sent via a line~ object. And meter~ and levelmeter~ objects are used to display signal levels.

Probing

One key debugging feature for audio patchers is the probing feature. In the debug menu, turn probing on. With probing on, you can hover your mouse over an audio patch cord and see the current signal level displayed as a popup meter. Since the probe is reading amplitude values at the beginning of every signal vector, it will fluctuate some. Still, it is a very useful tool for seeing if signal is present without having to add meter~ objects everywhere.

max max-lecturenotes

(max) line~, meter~, and levelmeter~

Three objects worthy of a special mention right from the start are line~, meter~, and levelmeter~.

If you have any sound experience at all you know to keep track of your visual indicators (meters) to make sure sound isn’t clipping at some point in the signal chain. In MaxMSP you have the meter~ and levelmeter~ objects to show audio levels. Meter~ can be arranged to be either horizontal or vertical, and sized according to visual need. You should insert meters into your patchers at all points that could output an original and/or a modified audio signal. This technique is like using number boxes for display purposes. Meter~ can be set to show more segments to give a more finely tuned display. Levelmeter~ is a bit more sensitive and finely tuned by default, but it is also a little more processor/graphics intensive.

The line~ object will create a smooth ramp to a specified value over a specified time (generally in ms). You will use the line~ object to create amplitude envelopes and frequency envelopes, and to smooth control-rate changes being used as arguments to audio-rate objects. For example, if you use a float object to type in a frequency change to an oscillator (saw~, cycle~, etc.), you need an audio rate ramp to smoothly change between the previous and new values.

Line~ expects <targetValue> <time> pairs. Multiple pairs can be sent as one message list and line~ will execute all the pairs at the proper time. A value followed by a comma tells line~ to immediately change to that value.

Line~ is often used to create a smooth ramp between amplitude multiplier values being sent to the *~object. I often use a floating point number box feeding a message object with the contents <$1 10>. The floating point number replaces the $1 and causes the list to be output to line~. The tutorial (MSP tutorial number 2) uses a pack object with arguments <0. 100>. The amplitude replaces the 0. and outputs the list. Either way is fine. Note that a message box doesn’t require you to format your argument according to data type. Pack does, however, want the argument to match the incoming message type. If the message and argument do not match, the message will be changed to the argument format. For example, if you type an integer as an argument to pack but send it a floating point number.

max max-lecturenotes

(max) audio basics in max

Before I dive into the Theremin patcher, it’s good to review basics of digital audio in Max. For that, I’m going to use a previous post to give the overview.

MSP and Audio Rate Communication

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-assignments

(max) midi performance project

Project 1 | MIDI Performance Patch
DUE: 2/10/14

ASSIGNMENT: to create a MIDI performance patch that utilizes the several different methods of data manipulation to control basic MIDI parameters. You will perform the resulting composition in class during a performance session.

GENERAL GUIDELINES:

  1. This project will build upon the MIDI manipulation techniques that we have discussed in class. Your objective should be to use the data storage objects (tables, histograms, coll, umemu, tab, etc) to control basic MIDI parameters (pitch, velocity, program change, duration). You may include an LCD with your patch if you wish. You should make every effort to be creative with this project. Draw upon your knowledge of experimental art music forms and unique beat-based compositions.
  2. You should complete a composition to perform that is ONE MINUTE in length. Some elements to consider include: changing pitch ranges, durations, velocities both within sections, and within gestures. Your composition should feature some real-time controls (either mapped to the computer keyboard or a MIDI device) and at least 3 different musical ideas.
  3. Write a brief report (two pages, typed, double spaced, 12-point font, 1 inch margins) describing the sounds you chose to use, the use of your Max patcher to control sound parameters, the use of your Max patcher to control performance, and any real-time input via keyboard or MIDI controller that you use. In your report, also briefly summarize the central organizing idea of the composition/improvisation, and describe the formal structure (or organizing aural features). Make any other comments you feel are relevant.

PROJECT SPECIFICATIONS

  1. At least 5 controllable parameters. This may include pitch, velocity, duration, program changes, range of pitches used, offset of patterns, etc.
  2. Your project should be at least 1 minute in duration.
  3. Your project should make use of layering as means creating a complex sonic texture.

FILE ORGANIZATION:

  1. Your Max patch should be labeled “yourLastName_yourFirstName_MIDI.maxpat”.
  2. Your studio report should be labeled “yourLastName_MIDI”.
  3. All of these materials should be placed in a folder labeled “yourLastName_MIDI_450”.
  4. The folder “yourLastName_MIDI_450” should be zipped into a folder.
  5. Submit by the due date, beginning of class, via iLocker, yousendit, dropbox, etc, with a link emailed to me.

YOU WILL BE GRADED ON THE FOLLOWING:

  1. Creativity of patcher and performance (30 pts).
  2. Neatness and documentation via comments (and/or send/receive as appropriate) (15 pts).
  3. Meeting the 1-minute length of performance and having the required 5 parameters under patcher control/variation (10 pts).
  4. Following turn-in procedure (5 pts).

60 points total

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.