News: MaxScore is here!!!
MaxScore provides you with common music notation directly in the Max/MSP environment. MaxScore is a Max object which accepts messages that can create a score, add notes to it, perform it, save it, load it, and export the score to popular formats for professional publishable results. MaxScore is also an interactive performance object, and can play back a score that drives your MSP patches through a well-defined instrument interface.

Using JMSL with Max/MSP

Read on if you want to write your own systems that communicate between MaxMSP and JMSL. If you need music notation in MaxMSP then use: MaxScore

With the introduction of a Java API in Max/MSP, bidirectional communication with JMSL is possible. This opens the door to hybrid musical pieces that leverage off the strengths of both software systems.

Java Music Specification Language is a Java API for algorithmic music composition and interactive performance and is available from www.algomusic.com. Max is available from www.cycling74.com

JMSL can send and receive musical data to and from Max. With JMSL's MaxInstrument, you can play MSP instruments directly from JMSL. This allows you to create notated musical compositions which control MSP audio, as well as non-notated algorithmically generated or interactive works that send data to Max and MSP (and for example, with the rtcmix~ object, control RTcmix in realtime as well).
Going the other way, any data you generate in Max can be read by JMSL. For example, the melodies you generate in Max can be captured and transcribed by JMSL and displayed in common music notation. The data sent from Max to JMSL does not have to be notated of course. It can be used to control or inform musical processes in JMSL in any way you see fit.

Why would a Max/MSP user need JMSL? Because JMSL is a music API that lets you model musical systems in ways that may be very difficult in Max's circuit paradigm. It is quite easy to spawn new musical objects on the fly, and launch new independently scheduled processes in JMSL, for example. Java is a general purpose programming language with real object orientation, inheritance, and reflection (ie the ability for an object to discover and reveal information about itself). JMSL leverages off these strengths, providing high level tools like an abstract Instrument interface, polymorphic hierarchical scheduling, tuning classes, and a rich set of musical abstractions that provide the user with the tools to model musical forms that have nothing to do with inlets and outlets. Finally, JMSL has a programmable common music notation editor which brings musical notation to the Max user.

Why would a JMSL user need Max/MSP? Certain things are very easy to do in Max/MSP. Max objects that read sensor data for example, are readily available and straightforward to use. Instead of writing your own native library, the JMSL user can simply use Max as the interface to the sensor data, and read the data stream into JMSL. Furthermore, MSP is an excellent software synthesizer with a large library of of unit generators. The JMSL composer can now control patches made in MSP. And with the rtcmix~ Max object ( http://music.columbia.edu/cmc/RTcmix/rtcmix~/rtcmix~.html ), you can even control RTcmix instruments real-time via Max (at ICMC 2006, Lang Crawford and Nick Didkovsky presented a version of MandelMusic that played RTcmix instruments by sending data to the Max rtcmix~ object). By using Max, the JMSL user can leverage off of a legacy of tools that have been developed over the years for these more traditional and popular technologies.

This document shows you how to set up JMSL to be used with Max/MSP.
Three examples are included:
  • a quick start "Hello World" style example where you will compile the Java source yourself
  • An example that transcribes Max-generated music into common music notation using JMSL Score. (requires no programming)
  • An example that uses JMSL Score to play instruments designed in MaxMSP (requires no programming)

    Installation

    Copy jmsl.jar and jscore.jar to the Cycling '74/java/lib folder (the same folder where you will find max.jar )
    In Windows XP this is most likely located in C:\Program Files\Common Files\Cycling '74\java\lib
    (or if you only have Max Runtime installed, C:\Program Files\Cycling '74\MaxMSP 4.5\Cycling '74\java\lib )
    In OSX this is most likely located in Mac HD/Library/Application Support/Cycling '74/java/lib

    Programmer's start: HelloMaxJMSL

    You will create a MaxObject whose constructor creates and launches a JMSL MusicJob. A MusicJob repeats a user-defined action over time. It has a "repeat count" that determines the number of times it repeats this action, and a "repeat pause" that specifies the duration between repeats ( see MusicJob tutorial and Java docs).

    Compile the following source.
    import com.cycling74.max.*;
    import com.softsynth.jmsl.*;
    /**
     * @author Nick Didkovsky, (c) 2004 Nick Didkovsky, all rights reserved. 
     *
     */
    public class HelloMaxJMSL extends MaxObject {
    
    	public HelloMaxJMSL() {
    		post("Hello JMSL and Max");
    		MusicJob job = new MusicJob() {
    		// override repeat() to do whatever you want
    			public double repeat(double playTime) {
    				post("JMSL MusicJob repeating at " + playTime);
    				return playTime;
    			}
    		};
    		// repeats 100 times
    		job.setRepeats(100);
    		// waits 0.5 sec between repeats
    		job.setRepeatPause(0.5);
    		// go!
    		job.launch(JMSL.now());
    	}
    
    }
    
    Copy the two resulting class files to Cycling '74/java/classes
    HelloMaxJMSL.class
    HelloMaxJMSL$1.class

    Note that the second of these is called an "inner class" in Java parlance. The inner class in this case is the MusicJob that was defined in the HelloMaxJMSL() constructor.

    Launch Max/MSP and create new patcher. Add a new Object and type in "mxj HelloMaxJMSL" (no quotes), as is shown in the screenshot below. Once you're done, watch the console and you will see the repeated postings of the MusicJob as it executes its repeat() method every 0.5 seconds.

    MaxMSP screen shot running a JMSL MusicJob

    Example #2: Transcribe a melody created by Max

    This example provides you with a powerful tool to notate music generated by your Max algorithms. JMSL listens to incoming pitch and velocity data, captures it in a MusicShape and transcribes it, finally displaying a notated score.

    This score can be saved, edited by hand, and further transformed using JMSL plug-ins.

    Finally it can be exported to MusicXML for import and printing in Finale, or exported to San Andreas Press's SCORE Computer Music Typography System. You can also assign JSyn instruments to your score and publish them on the web. Users will see and hear the score play back exactly as you expect ( no midi mapping issues, etc ).
    Open the JMSLNotate.mxb Max Patch as shown in the image below (see the maxmsp folder in your JMSL distribution). It generates a melody which JMSL captures using the example JMSLMaxNotate class.
    JMSLNotate by Nick Didkovsky
    Max patch which generates random melody. User changed the metro tempo continuously during playback.
    Max melody transcribed by JMSL
    Max melody transcribed by JMSL.
    JMSLMaxNotate source code This class is part of core JMSL now, so you do not have to compile it. Source for tutorial purposes only.

    Example #3: Play MSP instruments from JMSL

    Thanks to the efforts of Langdon Crawford and ND, JMSL now has a well-defined API for sending performance data to Max. Max objects are included that handle the playing of MSP patches. This example shows you how JMSL can send performance data directly to Max and control MSP sounds.
    Copy all the patches found in the maxmsp folder to your Max search path. If you are not sure where that is or you are using the run time, put them in the "patches" directory in your max4.5.x folder.
    From Max, open JMSLScorePlayMSP.pat. See image below.

    Click makeScore, and a JMSL Score window will open (see image below). Note that each staff has been already set up with a JMSL MaxInstrument. Windows users right click on the staves to enter notes. OS X users Apple-click on the staves to enter notes.
    After you have entered some notes, click the MSP audio icon in the Max patch and click the Play button in JMSL Score. You will hear two MSP instruments being performed by JMSL Score! JMSL Score with Max Instruments

    JMSL + MSP, going deeper

    Here we describe how you can gain full control over your MSP patches. The example above uses a simple duration/pitch/amplitude model for playing MSP sounds. But your MSP patches are likely to have more complex inlets, like filter cutoff frequencies, resonance values, Q widths, modulation index, etc etc etc.

    JMSL has a well-defined model for handling parametric data with its DimensionNameSpace model. A DimensionNameSpace is a mapping of integers like 0, 1, 2, 3, 4 .. to meaningful names like "duration", "pitch", "amplitude", "resonance", "cutoff", etc. When you instantiate a MaxInstrument in JMSL, you may specify its custom DimensionNameSpace either programmatically or through a GUI.

    In JMSL Score for example, you would select the MaxInstrument from the Orchestra menu, select Edit, and up pops a DimensionNameSpace Editor. Here you can add and name dimensions and set their min/max/default values. In the image below, the user has added two custom dimensions that are particular to the MSP patch: cutoff, resonance, and slew time.
    IMPORTANT: Do not remove or edit the EventFlag dimension! It is set and used internally at runtime to flag event types.
    Edit DimensionNameSpace for a MaxInstrument, to control MSP inputs

    Then you would add Notes to the Score, select one or more notes, and choose Edit Selected Notes from the Edit menu. You may then modify the values for each dimension on a per note basis, and control MSP inputs from your composition. In the image below, the user has changed cutoff, resonance, and slew to new values for notes that were selected in the composition. When the Note is performed, these values will be sent to Max/MSP. Note that you can change these values while JMSL Score is looping a section, and hear changes in real-time.
    Edit parameters of notes

    When MaxInstruments perform, they send their performance data to the JMSL object JMSLInstrumentToMax. If you pass the output of this object to a route object, the first value you get is an instrument index (0, 1, 2, ...). This lets you differentiate between the data coming from MaxInstrument-0, MaxInstrument-1, MaxInstrument-2... and send the data onwards to the desired MSP patch.

    Open the poly~ patch in the example, then open the "p synth" patch to see where to fit your MSP patch. The patch will look like so:
    here is where you substitute your own MSP patch
    You see two [unpack] objects. The one on the left will always receive pitch, amplitude, duration, sustain flag, and timestamp data from JMSL's MaxInstrument. Higher dimensions that you defined in the instrument's DimensionNameSpace will arrive as higher numbered params which you can pull out with the [unpack] object shown at the top right of this patch. In this example, Lang uses cut off, resonance, and slew time parameters to control his MSP patch beyond pitch and amplitude.

    What is sustain flag? JMSL Instrument supports four general operations: on(), off(), play(), and update().
  • on() turns a voice on and lets it sound indefinitely
  • off() turn a voice off
  • play() turns a voice on for a specified duration (called "hold" time in JMSL parlance)
  • update() looks up a voice and changes its synthesis parameters These behaviors are flagged as they arrive in Max as follows:
        MAX_INS_OFF = 0;
        MAX_INS_ON = 1;
        MAX_INS_UPDATE = 2;
        MAX_INS_PLAY = 3;
        
    For example, in JMSL Score, a Note tied out to a second Note would result in a call to play() followed a moment later by a call to update(). You might elect to bang your MSP patch's attack envelope when play() arrives and simply change resonance and cutoff when update() arrives.
    For another example, you might have an algoruthmic process in JMSL that calls on() on a voice when it begins, and spends 5 minutes making rapidly repeated calls to update() either under gui control or programmatic control. The design is up to you of course, but through on(), off(), play(), and update(), JMSL provides you with a well-defined interface to control MSP sounds both on a sound-event paradigm as well as a more fluid allocate-and-update paradigm.

    We hope this document got you jump-started in using JMSL and Max as a powerful bidirectional hybrid musical environment.

    This doc prepared by Nick Didkovsky, didkovn@mail.rockefeller.edu
    JMSL Home