The Development of Jamoma


The Jamoma Project recently released version 0.2 of its modular framework for Max, MSP, and Jitter. Despite the low version number this software is actually quite mature, which years of development and experience forming the basis of the framework. Given that this is a significant release in Jamoma’s roadmap, I thought I would talk about both Jamoma and it’s development.

What is Jamoma?

So, the first thing you are probably wondering about is what Jamoma is all about. Jamoma is a structural framework for creating, composing, and performing interactive music with Max. It does this by providing a set of guidelines for the construction of interchangeable, reusable, functional blocks (patches), called modules. In addition to the guidelines, the Jamoma Project has also produced an implementation of those guidelines.

Jamoma has been built around the advanced features in Max 4.5.5. Jamoma modules may encapsulate any type of functionality that can be performed by Max, MSP, Jitter, its components (such as Java or Javascript), or any third-party objects. It provides features such as fast DSP routines, XML-based preset storage, preset interpolation on both local and global layers, parameter mapping, and realtime CPU-load management.

Motivations

The promises of any object-oriented environment is that components can be created, and then freely re-used. This is certainly true of Max as well. However, when a user tries to substitute a component of their patch, there is generally no standard to which the components (patches) are structured. This is actually a strength of Max, as it doesn’t impose its vision of how one should work on you.

Unfortunately, it is rare that patches can actually be interchanged between users (and auditioned) without a significant amount of work – work both learning the ins and outs of the new patch, and configuring the patch to work in the user’s own system of patches. This is the first of Jamoma’s primary goals: to provide a standard to which patches/modules are structured to allow for easy interchange and integration.

A second goal of Jamoma is to provide standard tools – that are virtually always required – with a minimum of time needed to set them up. As an example, audio modules will almost always benefit from a mute button, a bypass button, a gain control, signal level meters, etc. Video modules will benefit similarly from bypass, mute, and freeze controls as well as a preview pane. Jamoma provides templates and tools that incorporate these features with a minimal amount of setup time.

The third goal of Jamoma is provide hierarchical organization of the parameter space. Every module maintains its state, and provides a mechanism for reading and writing preset files specific to that module. Furthermore, global snapshots or presets may be created and maintained that apply to all instantiated modules via the use of Max’s standard pattrstorage object. This also provides a means to interpolate smoothly between presets to simplify complex transitions.

History

Jamoma grew out of initial research and development that was conducted as part of the Jade interactive performance environment. Jade is an application that hosts modules, which allows for script-based automation of these modules. Initial development on Jade began in early 2001 as a means to aid my own compositional work. It was released to the public at the end of 2002, which was followed by a significant update to version 1.1 in mid-2003. It was at this time that the great benefit of having modules directly within Max was realized – and Jamoma was born.

The Jamoma project was started as an Open Source project hosted on SourceForge. After some initial work activity died off until it was revived in March 2005 by myself and Trond Lossius.

Module Structure

A Jamoma Module is a Max Patch which has been structured according to a set of guidelines known as the JIG (Jamoma Interface Guidelines). Modules may either be embedded in a Max patch using the popular bpatcher method, or they may be included as simple Max objects. The screenshot shown here is an example of the two methods side-by-side. The filter module is one of a number of example modules included with Jamoma.

Every module will have one or more inlets and one or more outlets. The first inlet is used for receiving all commands to the module. Likewise, the first outlet is used to report the state of the module and return parameter values when they change. Additional inlets and outlets are the inputs and outputs for data streams that are to be processed or synthesized by the module. This includes audio, midi, and video signals.

This screenshot shows the filter module in context. In this example it is being used to filter the signal from MSP’s standard soundfile playback mechanism. Note the presence of a “bang” button connected to a Max send object called jmod.init. This mechanism is required, and provides a universal means to reset all modules that are loaded to their respective initial state.

Standard Elements

The JIG specifies a variety of essential elements to ensure that modules are both interchangeable and compatible with each other. This includes the size(s) of the user interface, standard features, and reserved messages and syntax.

For example, every audio module is expected to implement the ‘gain’ parameter, which attenuates or boosts the output signal, specified in decibels. Each audio module should also implement the mute and bypass messages. No module may implement a message called bang, it is considered a reserved name due to its special nature in the Max environment.

Further, for all module parameters where it is feasible, the parameter should be ‘ramp enabled’. This means that when a second value is given to messages for the parameter, it will smoothly slide from its current value to the new value. This is aided by a set of tools for building modules that we will described later. An example of a ramping parameter is demonstrated in this screenshot.

Hierarchical Parameter Space

One of the standard features of all modules is the ability to read and write presets in an XML file format. The facilities may be accessed as one of the standard Jamoma messages. Additionally, most Jamoma modules use standard facilities that provide a “module menu” in the upper left corner of the interface that include items for reading or writing a preset. (As a historical note, Jade was reading and writing presets in XML format prior to the release of pattrstorage, but it now uses pattrstorage to simplify and standardize the system).

The preset mechanism in these modules is built on the pattr system that was released as a part of Max version 4.5. This mechanism allows not only local preset reading and writing, as just demonstrated, but global access to the Jamoma parameter space through the standard pattrstorage object. This allows for the storage and recall of global presets and interpolation between those presets. The screenshot below shows an example of pattrstorage managing several modules.

Building Modules

Modules can be constructed from scratch following the guidelines published in the JIG, or they can use the extensive library of pre-made components that are a part of the standard Jamoma package.

Our screenshot shows the construction of a simple Jamoma module. This module consists of several key components:

  • GUI Component: The black metal background, which includes built in signal meters, bypass and mute buttons, sample-rate reduction (for managing CPU load), gain control, and module menu. The standard Jamoma package includes a variety of these in different sizes. It is automatically configured (using Max’s scripting) for use in audio, video, or control contexts. It is also skinnable – meaning that the appearance can be customized for a look other than the brushed metal that is the default.
  • jmod.hub: The core of the message handling, preset management, and additional functionality. This component shares an invisible connection to the Gui Component to link them. It is connected to a pattrstorage to provide a tie into Max’s pattr system.
  • poly~: Most audio modules will use a patch (in this case degrade.lib) that is loaded in a poly~ object. This provides the mechanism for downsampling and muting. Additional options are available. For example, many Tap.Tools 2.0 externals have integrated mute, downsampling, and bypass capabilities. Video or control modules can use a simple patcher.
  • jmod.parameter: this object creates a parameter and links it to the jmod.hub component. Various attributes can be established such as enabling automatic ramping capability (as seen in a previous section of this paper), decibel conversion, or the filtering of duplicate values.

Automatic Documentation

One particulary time-saving feature for module developers is a built-in facility for producing module documentation based on the patch. Using a combination of patching and JavaScript developed by Trond Lossius, this allows you to send a message to a module and save an HTML pages with all of the information on how to use that module.

Recapitulation in the Key of Licensing

When a user begins with Max/MSP, they are presented with the paradigm of a blank document (see David Zicarelli’s CMJ article “How I Learned to Love a Program that Does Nothing). This proves to offer the user the ability to work with the software in any way that they like, offering no preconceived notions about how a module should be structured. This is both a blessing and a curse. While not limiting the user, it also provides no guidelines to help the user get started. It is our hope that Jamoma will be helpful for both long time users and beginners alike.

By providing a mechanism by which a patch must be structured, interchangeability can also be guaranteed. Many new Max users can thus be re-assured that any patch they develop will be able to be re-used. They will also find that they can use a variety of patches developed by others that conform to the JIG. Jamoma also encourages good structure and form for students beginning to use Max.

Jamoma is licensed under the terms of the LGPL, thus making it freely available for use in both commercial and non-commercial applications. This licensing was chosen for the purpose of helping to establish and encourage adoption of the system.