Posted by & filed under Bitwig Studio, Blog, Tutorials.

In the last article we managed to bundle a bunch of transport related code into one function and import that function into our script. This is great for encapsulating code, but we are overlooking one of the biggest boons of javascript: the ability to create objects. Everything in javascript is an object. Functions, variables, arrays, everything. You can give objects properties and you can assign objects functions (called methods). For more information on working with and defining objects in javascript I encourage you to consult THIS PAGE from the Mozilla Developer Network.

To demonstrate the basic construction and use of an object in javascript let’s reproduce the behavior we achieved by defining the transport_functions() function with an object. We will also wrap our LED transport feedback into this object, consolidating all of our transport related code into one place.

The easiest way to create an object is to define a variable as an object using a Object Literal Notation, like so:



This creates a new empty object called mcTransport{}. Curly braces are used to denote objects in javascript. As an empty object, this is just another variable in our script. Within the Object Literal, we can assign properties and methods to our object that can be used within our script. Let’s begin by giving our new object some properties.



Now our mcTransport{} object can keep track of its playing and recording state. We can define functions in the same way. Let’s go ahead and add the code that is used to control the transport in Bitwig to a function named input below the property definitions:



We can call mcTransport.input() to play, stop and record arm our session! (Of course you may have to change the data1 checks to correspond to your controller or MIDI messages you are sending). We can access these properties and methods a few different ways, but I am a fan of using dot notation. If you call mcTransport.input() somewhere in the note section of onMidiPort1(), you should get the same behavior that we had previously, but in a higher level form.

The other thing we’d like to add to our mcTransport{} object is the LED feedback that we have included in the observer callbacks. If you recall, observers with callbacks look something like this:



This is kind of messy and not very descriptive, especially at the top level of our script. I’d like to avoid having a ton of MIDI bytes clogging the main script in case some one wants to modify this in the future, or if I want to quickly figure out what bit of code is doing what. We can house this code (and the code from our recording observer) in a single output function that we will define as a method of our mcTransport{}.



The output() method introduces the this keyword. This simply means the object that this method is associated with. For example, in this context, this.playing == mcTransport.playing. Whenever we call the output method, we check the state of our session by asking if it’s playing, if it’s recording, and then send the appropriate MIDI values out. To regain all of our original functionality in this object based approach, we need to modify our callbacks to update the state of our mcTransport{} and to call the output() method. Our two observers with callbacks now look like this:



Our script is clean, readable, and easily expandable. Using objects in this way allows us to keep all of our messy conditionals, logic, and function definitions tucked away behind the scenes. In the next article, we’ll take it one step further and reclass the built-in transport object to include our custom functionality!

Direct all questions comments and concerns to