by Sam Walker-Kierluk
In this age of innovation in the area of digital musical instruments, ever-increasing numbers of interested musicians and programmers are experimenting with the development of new and exciting pieces of hardware and software that are redefining what we think of as instruments. The creation of applications that act as instruments, or fulfill other custom audio synthesis and processing needs, has become accessible to even the most novice of computer users, thanks to visual programming environments like Max and Pure Data that are designed primarily for audio purposes. libmapper is a software library for connecting virtual data signals locally or across networked computers running, providing tools for creating and using systems for interactive control of media synthesis, and is able to integrate effectively with programs like Max and Pure Data.
In this tutorial, I will demonstrate how to transmit numerical data from one Max project to another Max project using the libmapper library and its associated tools.
libmapper is an open-source software with cross-compatibility among many software environments. The developers have already created the two tools needed to use libmapper with Max: external objects for Max, and a graphical user interface (mapperGUI) to perform mapping operations among the objects. The software can be downloaded at http://idmil.org/software/libmapper/downloads, where installation instructions can also be found.
libmapper can be used only to transmit integers and floating-point numbers.
Creating and defining sources and destinations in Max patches
1. Create/open the two Max patches between which you intend to transmit information. These can both be running on the same computer, or can be running on separate computers, each running Max, as long as they are connected via a Local Area Network connection (typically Ethernet or Wi-Fi).
For your source patch:
2. Go to the patch that contains source data. This could include any data-rate (not audio-signal-rate) generator, such as the output of a slider or number box.
3. Create a new object box, and type map.device [patchname], where [patchname] is the name you wish to give to that specific patch on the network. You must not use any spaces in your naming scheme in libmapper, as this will cause errors and much frustration. For our purposes, let’s call this device “signal_source”, meaning we’d create an object box and type map.device signal_source.
For each data stream source you wish to make:
4. Create a new object box, and type map.out [sourcename] [i/f], where [sourcename] is the name of this source, and i or f sets whether it will be sending integers or floating-point numbers, respectively. Optionally, you can add the arguments @min [minvalue], @max [maxvalue], and @unit [unit], the first two of which define the range of the values received by the map.out box, and the last of which labels the data’s measurement unit for convenience later on (Hz, for example). Defining the range of values allows you to use libmapper’s powerful scaling features after you complete your patching. In this example, we’ll make a box containing map.out “pitch_raw” i @min 0 @max 1023 @unit pressure.
For your destination patch:
5. Go to the patch where you wish to send the data.
6. Create a new object box with the map.device object (see step 3), with your desired name.
For each data stream destination you wish to make:
7. Create a new object box, and type map.in [destinationname] [i/f], with a similar manner to step 4. Fill in the arguments for scaling, if you will use this feature, as well as the @unit argument for convenience, if appropriate. For our box, we will use map.in frequency f @min 440 @max 880 @unit Hz.
Creating Mappings in mapperGUI
1. Launch mapperGUI, an application for configuring libmapper data mappings. Although libmapper is cross-platform, and Max externals are compiled for Mac OS X and Windows, mapperGUI and other libmapper GUIs are only made for Mac. However, these GUIs can perform mappings for libmapper instances running on PCs and Macs if they are connected on the same local area network.
2. Once the application has opened, observe the three main columns in the window, Sources, Links, and Destinations. In the Sources column, you should see an entry called “/signal_source.1” or whatever you named your source patch with the map.device object. This will provide information including the number of inputs(map.in)/output(map.out) contained within the patch, the port on which the patch communicates, and the IP address of the machine on the network. In the Destinations column, you should see an entry called “/destination.1” or whatever you named your destination patch with the map.device object. The Links column should be empty.
3. First, we must tell libmapper that you wish to route data from your source patch to your destination patch. To do this, click and hold on top of the entry for “/signal_source.1” in the Sources column, drag across the Links column, and release the mouse button on top of the entry for “/destination.1” in the Destinations column. A line will appear linking the two entries. If you wish to have one source patch transmit to more than one destination patch, create multiple “Links” from that source by clicking and dragging to each one.
4. Next, click on the tab for your source device that is listed above the three columns, next to “All Devices.” Ours will be called “/signal_source.1”.
5. You will see three columns as before, but this time, Sources will show your map.out object name(s) within your source patch, Destinations will show your map.in object name(s) for all available destinations to which you have linked, and the “Links” column is replaced by “Connections”.
6. To connect a source to a destination, drag from the source, across the Connections column, to the destination, similar to step 3. As with step 3, you can connect one source to more than one input.
7. That’s it! Any data sent into the inlet on your map.out object will be sent to any map.in objects to which you have connected it. map.in objects will receive the number in whichever format is specified in their name, regardless of the originating type of data, meaning floating-point boxes will output all numbers received as floating-point numbers, regardless of how the data was sent, and integer boxes will output all numbers received as integers (floating-point numbers received by integer boxes will be rounded down to the nearest whole number).
Connection and scaling options in libmapper using mapperGUI
By default, if the @min and @max values have been specified in the Max objects, libmapper will scale the numbers streamed from object to object using these parameters in a linear fashion. In our case, the “pitch_raw” source’s range of 0-1023 will be mapped only the “frequency” destination’s range of 440-880.
1. To set connection preferences in mapperGUI, click on a connection from a source map.out object to a destination map.in object. The line and objects will become highlighted.
2. At the top of the mapperGUI window, just under the title bar, there will be a group of boxes: Mute, Byp, Line, Calib, Expr, and Rev.
• “Mute” temporarily disables all throughput on a connection without permanently removing it.
• “Byp” disables scaling, and all number will be unaltered from source to destination.
• “Line” is the default option, and scales numbers linearly based on source and destination ranges.
• “Calib” lets you calibrate the input range based on real-time input data and the preset output range.
• “Expr” lets you transform source numbers using a mathematical expression.
• “Rev” is a feature that lets you reverse the functionality of a set of map.out and map.in boxes, with all scaling bypassed.
3. Finally, connections and settings within the Sources-Connections-Destinations can be saved and recalled by using the Load and Save buttons in the top-left corner.
Although not a complete guide to using libmapper with Max and mapperGUI, this should serve as a functional introduction to allow for quick patching and experimentation in the development and use of digital musical instruments and other media projects.