Motion Capture Music (MCM) is software for mapping motion capture data from a Vicon 8 system into music control data such as MIDI. This page describes the Macintosh version of MCM, called MCMMax. On other pages you can read a description of the Windows version of MCM, and an overview of the research work being done at UCI on the use of the Vicon motion capture system for generating and controlling music.
MCMMax is the version of MCM for Macintosh. It's written in the Max/MSP/Jitter programming environment by Cycling '74. It's a collection of Max patches (a.k.a. abstractions) to facilitate mapping the data from a Vicon motion capture system into music control information. Because Max/MSP/Jitter integrates MIDI, software audio processing, software video processing, and computer animation, MCMMax allows one to map Vicon motion capture into any of those other media.
The ways one could possibly map motion capture data in musical information are practically infinite, so MCMMax strives to simplify that task while retaining optimum flexibility. We do that by combining existing Max objects with abstractions specially suited to the goals of MCM. In short, we try to make it as easy as possible to control music with motion in any relationship desired.The basic MCM idea is this: receive the mocap data from the Vicon system, identify and parse the data we're interested in, specify a mapping of that data into musical control data (MIDI messages or MSP control signals), and apply the mapped data to produce music. MCMMax provides subpatches for each of these tasks, with the intention that someone with a basic understanding of Max/MSP can assemble these subpatches, in combination with basic Max/MSP objects, to make practically any gesture-music relationship they can imagine.
Here is a listing of the objects in MCMMax that are applicable to each of those tasks:
Objects for receiving realtime mocap data from a ViconRT system or the RTemulator
Objects for simulating realtime receipt of mocap data
playfile [requires Jitter]
Intended to be used as a subpatch in a larger mapping program. Double-clicking on it reveals its user interface. It allows you to read in a text file of marker data and an associated movie file. When the movie file is read in, playfile automatically gets the number of frames and the proper rate for the metronome. It automatically sends the number of frames to any open patch that has a "receive howmanyframes" object in it (see trackonecoord). It reads the marker data into a coll object named "markerdata", so any other coll object can refer to it by that name (also see trackonecoord). As the movie is playing, it sends the current frame to any open patch that has a "receive frame" object in it, and it sends all the marker data out its outlet.
Objects for identifying particular location (coordinate) data in a frame of mocap data
Takes a list of an entire frame of marker data in its left inlet, and outputs only the desired marker and coordinate. The marker and coordinate can be specified as typed-in arguments, or in the second and third inlets, or chosen from popup menus inside the object. Need more than one coordinate? Just use two or more of these objects and send the same marker data to all of them. Need all three coordinates of the same marker? In that case, maybe you'd prefer...
Takes a list of an entire frame of marker data in its left inlet, and outputs only the desired marker, as a three-item list of xyz data. The marker can be specified as a typed-in argument, or in the second inlet, or chosen from a popup menu inside the object.
This patch is designed for tracking a single marker coordinate with ease. It is intended to work in conjunction with the playfile patch (see above). The arguments (which can also be sent in the 3rd, 4th, and 5th inlets) are the name of the coll file to refer to (should be "markerdata" if used in conjunction with the playfile patch), the marker number, and the coordinate desired. For example, an object "trackonecoord markerdata 17 2" would track the "right finger" marker (markers are numbered starting with 0), looking at the "z" coordinate (xyz=012), of the marker data file contained in the coll object named "markerdata". When a frame number is received in the left inlet (or is sent in by a "send frame" object from another patch), the data in that frame of the data file, for that marker and that coordinate, is sent out the left outlet. Also, at the moment when the movie file is loaded in the playfile patch, trackonecoord scans the entire data file (in the named coll) to get the minimum and maximum values that occur for the named marker coordinate, and sends those out the 2nd and 3rd outlets. This is very valuable for sending to the 2nd and 3rd inlets of a mapping patch such as linmap, expomap, tablemap, lookupmap, or lookupmap, to set the xmin and xmax values of the mapping patch.
Objects for deriving other meaningful information about marker coordinates
delta Reports the difference between the current incoming value and the previous incoming value. Note that since the frame rate is constant, this is equivalent to reporting the velocity in one dimension (you can then map the output to suit your needs). The input for this object would presumably usually come from choosemarker. The first incoming value produces no output because there is no previous value to compare with.
Takes two marker coordinates in its inlets, and reports the difference in location (i.e. the distance in 2D space) between the current incoming values and the previous incoming values. Note that since the frame rate is constant, this is equivalent to reporting the velocity in 2D space (you can then map the output to suit your needs). The inputs for this object would presumably usually come from two choosemarker objects, or from unpacked data from a choosemarker3D object. The first incoming values produce no output because there are no previous values to compare with.
Takes three marker coordinates in its inlets (or a list of three coordinates in its left inlet), and reports the difference in location (i.e. the distance in 3D space) between the current incoming values and the previous incoming values. Note that since the frame rate is constant, this is equivalent to reporting the velocity in 3D space (you can then map the output to suit your needs). The inputs for this object would presumably usually come from a choosemarker3D object (the list can be sent directly into the left inlet, where it will be unpacked automatically). The first incoming values produce no output because there are no previous values to compare with.
Same as delta, but wraps its output within the range -pi to pi, using a modulo operation. This is useful for finding the change between two angles, protecting against a misleading large change when the angle goes from pi to -pi or vice versa.
[Note for all delta objects: Feeding the output of any delta (or delta2D or delta3D) object into the input of another delta object will yield a value that corresponds to the acceleration of that marker. Also, the message "clear" will reset any of these objects to their initialized state, forgetting any previous values.]
Takes four coordinate values in its inlets, and assumes them to be x1,y1 and x2,y2. It reports the polar angle from point 2 to point 1, in radians, out the right outlet; it reports the linear distance between those two points out the left outlet. (Of course, the four incoming coordinates need not necessarily be literally the x and y of two particular markers; they can be anything.) Good for tracking the relationship between two markers in 2D space.
Takes two three-item lists (presumably of of xyz marker coordinate values) in its inlets, and assumes them to be the cartesian coordinates x1,y1,z1 and x2,y2,z2 of two markers. It reports the spherical coordinates of the marker in the left inlet, relative to the marker in the right inlet. It reports the third-dimension angle ("phi") out the right outlet; it reports the polar angle in the xy plane ("theta") out the middle outlet; it reports the linear distance between those two points out the left outlet. This tracks the distance and angle(s) between two markers in 3D space.
This patch facilitates tracking the distance between two markers. It is intended to work in conjunction with the playfile patch (see above). The arguments (which can also be sent in the 3rd, 4th, and 5th inlets) are the name of the coll file to refer to (should be "markerdata" if used in conjunction with the playfile patch), the marker number for one marker, and the the marker number for another marker. For example, an object "trackonecoord markerdata 17 12" would track the 3D distance between the "right finger" marker and the "left finger" marker (markers are numbered starting with 0), looking at the xyz coordinates of those markers in the marker data file contained in the coll object named "markerdata". When a frame number is received in the left inlet (or is sent in by a "send frame" object from another patch), the 3D distance between those two markers is sent out the left outlet. Also, at the moment when the movie file is loaded in the playfile patch, trackonedistance scans the entire data file (in the named coll) to get the minimum and maximum values that occur for the distance between those two markers, and sends those min. and max. values out the 2nd and 3rd outlets. This is very valuable for sending to the 2nd and 3rd inlets of a mapping patch such as linmap, expomap, tablemap, lookupmap, or lookupmap, to set the xmin and xmax values of the mapping patch.
Objects for mapping data from one type or range to another
Converts an amplitude expressed in the decibel scale into an amplitude expressed on a 0-to-1 scale. E.g., an input of 0 dB produces an amplitude output of 1; an input of -6 dB produces an amplitude output of approximately 0.5; an input of -12 dB produces an amplitude output of approximately 0.25, etc.
Same as linmap (see below), but with an added inlet (or argument) to specify the exponentiality of the mapping curve. Exponents greater than 1 cause an exponentially curved mapping; numbers between 0 and 1 cause an inverse exponential mapping; numbers less than 0 (not really intended) will cause output ranging from infinity to ymax.
Converts a float (or int) to an MSP signal, and ramps smoothly to each new value based on the frame rate (i.e., in 1/framerate seconds). The frame rate is sent in the right inlet, or is typed in as an argument. (If no frame rate is provided, the transition will be immediate, i.e. in 0 ms.)
The basic linear mapping function. The input x in the left inlet is mapped to the output y out the outlet, according to the linear mapping formula y=(x-xmin)/(xmax-xmin)*(ymax-ymin)+ymin. The values xmin, xmax, ymin, and ymax can be sent in the 2nd, 3rd, 4th, and 5th inlets, or can be typed in as arguments. This is functionally equivalent to the Max object zmap.
lookupmap [requires some MSP objects, but not MSP audio on]
A mapping function that uses the MSP object waveform to allow the user to draw a transfer function that will be used as a lookup table. (Uses 1001 floating point numbers in a buffer~, and does not perform interpolation between those points.) The inlets, outlets, and arguments are the same as the linmap object, but the output is warped according to the drawn transfer function.
lookupmap~ [requires MSP]
Uses a buffer~ containing an audio file of any length as a transfer function, and the output is sent in the form of an MSP signal. The audio file must first be read in with the message "replace" in the left inlet. Inlets and arguments are similar to linmap, and an additional final inlet (or argument) is used to specify the frame rate. The frame rate is used to ramp the output signal smoothly to each new value in 1/framerate seconds. MSP audio must be on for this patch to work.
pan~ [requires MSP]
A patch for implementing constant power stereo panning of an MSP signal, according to a value in the right inlet from 0 (left) to 1 (right). The panning value can be supplied as an argument, a float, or a signal.
sigmap~ [requires MSP]
Same as linmap, but for MSP signals. For most Mocap-to-Music purposes, this is probably less efficient than just using a combination of linmap and ftosig~. (Also, it doesn't have any protection against a divide by 0 if xmin=xmax, which could cause MSP to choke.)
A mapping function that uses a Max table object as a transfer function. You can draw any values from 0 to 100 in the table and it will use those as the transfer function, with interpolation as necessary. The inlets, outlets, and arguments are the same as the linmap object, but the output is warped according to the drawn transfer function. You can also save a table to disk with the "write" message in the left inlet, and you can read in an existing table with the "read" message. If you read in a table with a length different from the previous table (101 by default), you should send a "length" message after reading in the table; that will revise the mapping algorithm based on the new table length.
Objects for filtering data
A lowpass filter for smoothing data. The "inertia" factor in the right inlet (or typed in as an argument) is the intensity of the previous output value, mixed with (1-inertia) times the current input value. For example, an with an inertia of 0.5, the output will be halfway between the current input value and the previous output value; with an inertia of 0 the output will be the same as the input; with an inertia of 1, the output will be the same as the previous output. Inertia values are limited to the range 0 to 1. The first value goes out unchanged, since there was no previous value.
Same as the MSP object slide~ (see slide~.help for description), except for floats instead of signals. Has a strong low-pass filtering effect for all slide settings > 1.
Other miscellaneous objects
Takes a float in its inlet and reports the fractional part out its right outlet and the integer part out its left inlet. (Useful for interpolation of values between two locations of a table or a buffer~.)
Last modified May 9, 2003.