The JavaScript-mtr Connection, Part 1
The recent changes to the mtr object allow us to now access internal data in the form of a “dump dictionary,” a powerful feature that we can harness easily with scripting tools. This tutorial series will focus on using mtr with JavaScript.
In Part 1 of this series, we will introduce a JavaScript library called mtr-accessor which helps morph a dump dictionary into an easy-to-use format. We’ll show you:
- How to import the mtr-accessor library
- The structure and contents of the mtr data
- How to do a basic operation like printing mtr contents to the Max console
Get ready
This tutorial assumes you have reviewed the JavaScript Tutorial 1: Basic JavaScript introduction to using JavaScript with Max.
Download the patch used in this tutorial
Make sure to save these files in the same folder your Max patch will be saved, or in a location shared with all of your Max patches.
Now create a new empty file called “mtr-to-console.js” and save it in the same folder as “mtr-accessor.js”. This script will be where we write all of our code to access the shared library and send output to Max. It’s the JS to MTR connection!
Using require
Okay, let’s open up our script, “mtr-to-console.js” and add the following setup lines:
autowatch = 1; // Reload the script any time we save new changes inlets = 1; // One inlet to the js object outlets = 1; // One outlet from the js object var mtr = require(“mtr-accessor”); var myMtr;
The first var statement shows how “mtr-to-console.js” will use the contents of our shared library using the require statement. The second line sets up a global variable (myMtr) where our formatted mtr data will be stored.
Finally, let’s write the function that will fill up the myMtr variable with our easy-to-handle format!
function dictionary(v) { var d = new Dict(v); myMtr = new mtr.Mtr(d, 'dict'); }
What we’ve done here is take a dump dictionary in from the js object’s inlet and created a Dict object. To create an easy-to-handle object, we passing the Dict we just made into constructor for the mtr.Mtr() JavaScript object. Notice that the second argument to the constructor is ’dict’. The purpose of this will become clearer in later parts of this tutorial series, but for now just know that this tells the library the type of data being send it comes from a Max Dict object.
The data structure
The following diagram gives a general idea of what data is stored in a mtr.Mtr object:

- tracks: This holds “track” arrays which in turn hold event info, like event type and event value. Each event type is either a number or an array, making it much easier to handle all of the different possible kinds of inputs from Max!
- trackInfo: For each track, there is metadata info like track length, whether the track loops, and what speed to playback at.
- topLevel: This holds any miscellaneous top-level mtr data, like the type of dictionary input that is parsed.
- isValidInput: This is true if the data was parsed with a supported type, otherwise it is false. isValidInput will be true in our current example because we passed in a supported type (‘dict’) as the second argument to the constructor of mtr.Mtr().
Basic JavaScript access
Now that we have an overview of what’s available to us in myMtr, let’s access it! We’re going to step through the data in myMtr and print it to the Max console.
First, add the following helper function for printing a single line to the bottom of your “mtr-to-console.js” file:
function postln(v) { post(v + '\n'); }
Now, back in the dictionary() function, after the line you created myMtr, we can iterate through the data with the following code:
for (var n = 0; n < myMtr.tracks.length; n++) { var z = myMtr.tracks[n].length; postln(""); postln("Track " + n); postln(" Length: " + myMtr.trackInfo[n].length); postln(" Loop: " + myMtr.trackInfo[n].loop); postln(" Trackspeed: " + myMtr.trackInfo[n].trackspeed); postln(" Event Count: " + z); // the first and last event info (if available) if (z > 0) { postln(" First @ " + myMtr.tracks[n][0].accum.toFixed(2) + " ms"); postln(" Last @ " + myMtr.tracks[n][z-1].accum.toFixed(2) + " ms"); } }
Once you save the changes you’ve just made to the script, you can feed dump dictionary output into the inlet of your js object and see the data in your Max console window!
What’s next?
Now that we’ve shown the power of the mtr-accessor library, part 2 of this tutorial series will demonstrate using the jsui object as a visualizer for our mtr data. Stay tuned!