The Score Automator allows you to write, deploy, and execute complex automation scripts. It is the best way to write detailed, repeatable collections of events and can be used to control parameters with more granular control than any other part of the system. It is perfect for crafting repeatable compositions and can help you get fine control over your projects. Automation events can be executed by any of the control methods available in the platform.
Scores in MSDP are collections of automation messages that are executed all at once in a cluster referred to as an ‘event’.
Scores can be viewed in the Score Player module, but modifications can only be saved in MSDP if you are running the source code.
It is recommended that score modifications be made in your favorite IDE (Atom is used in the image above), and re-loaded to test out changes.
Scores are normal .txt file, so no syntax highlighting is available. However, learning to write a score is not a complicated process, and understanding a score is easy once you know how they are designed.
Each line of code in a score contains one or more automation messages that will go out to a single MSDP module.
The line consists of the following items:
- The name of the destination module followed by a space. If the ID includes one or more spaces, the entire ID needs to be wrapped in single or double quotes.
- One or more parameter controls messages. A parameter control message takes two arguments: the parameter name and the destination value. There is an optional third argument, which is glide time in milliseconds. Every parameter control is separated by a comma.
- A semicolon to mark the end of a line.
A parameter control message specifies a parameter to change, and how to change it. There are two required arguments for the control, and a third optional argument:
- The parameter name: The parameter name is the letter p, for parameter, followed by the appropriate parameter number. In the chorus module, volume is parameter 3, so its parameter name is ‘p3’. Output is parameter 2, so its parameter name is ‘p2’.
- The destination value. This value is based on the expected content of the parameter. For example, in the chorus pedal, volume expects a number, so the destination value may look like “1.2”. The output expects two letter/number pairs, so its value might look like “Master Out A 2”.
- The third argument, glide time, is optional, and determines how long it should take, in milliseconds, for the parameter to glide from its current value to its destination value. For example, if the chorus volume is currently set to 0.5, and we want to glide to 1.2 over 5 seconds, we can set the destination value to “1.2” and the glide time to “5000”. Note that not all parameters can glide, but most have the ability to.
Look back at the automation message above, and let’s disect what is happening.
- The message targets a module with the ID: 1 Tape Part. Notice that if an ID contains spaces, the name must be encased in either single or double quotes. If the module ID contains no spaces, quotes are not necessary.
- This is an audio file player, and its fourth parameter is the Play/Stop toggle. We are telling the player to begin playback by setting its state to ON, which is a 1.
- Next, we are setting the volume, parameter 3, to a value of 0. This will start the playback of the file in silence.
- Finally, we are turning the volume up to 0.8 (80% of full volume) and telling the dial to move there over 1000 milliseconds, or one second.
- The events occur sequentially, so this means that the file playback will begin, the volume will be set to 0, then the volume will glide up to 80% value over 1 second.
- This is great, and allows us to combine three automation commands into a single line of code! We could improve on it though, if even very slightly.
- We could have set the volume to 0 before beginning audio file playback, ensuring that there will not be any scenario where we hear any of the audio file before the volume ramps up.
Each event is comprised of one or more parameter automation messages sent out to one or more modules.
Each line of code contains a set of automation messages to send to a single module, and each set may contain one or more parameter changes.
The end of the ‘event’ is marked with a line that contains a single integer number. This number marks the end of the event and determines the number associated with it.
Automation messages in an event are all sent out together when an event is executed.
The automation messages occur sequentially, from top to bottom. The parameter control messages inside of the automation messages occur sequentially from left to right.
Look at the block of code above. Lines 1 through 12 contain a series of messages. Line 13 contains only the number 0. Lines 1 through 12 will be executed together as a series of messages grouped together in event number 0. Lines 14-16 contain another series of messages, and line 17 contains the number 1. Lines 14-16 will be executed together as a series of messages grouped together in event number 1.
The Score Automator Module
The Score Automator Module provides an interface for loading scores and executing the events within the scores. There are a number of steps and options involved in setup and execution of events.
- Load Score - When you begin working in the module, you’ll need to either load a pre-built score or create a new one. If you have a score that already exists, use the Load Score command to find it. Note that all scores should exist inside the “Saved Scores” folder in your MSDP project folder.
- New Score - If you want to start a new score, use this button to generate a score in the appropriate location in your MSDP Project Folder. You’ll be prompted to name the score, and the module will do the rest of the work of creating the blank document and loading it into the module.
- View Score - Opens the score up in a text editor window. NOTE: edits made in this window can NOT be saved by the application. Edits to the score should be made in your own IDE or text editor.
- Next Event - This button will trigger whichever event is currently queued up. If no event has been triggered, than pressing this button will trigger the first event in the file. Unless specified in parameter 6 (Skip to Event), the next event will always proceed to the event following the last one triggered.
- Skip to Event Immediately - Inputting an event number into this field will skip to that event number and will immediately trigger that event.
- Skip to Event (on next event) - Inputting an event number into this field will queue the event to be triggered the next time the ‘Next Event’ button is pressed.
- Control Method - The ‘Next Event’ button MAY be triggered directly by other means. The control method determines whether you’d like the event to be triggered via: a MIDI control value, a MIDI pitch value, the console metronome or the console clock. See the following section - ‘Controlling the Score Module with the Score’ for more.
- Control Value - This will determine the value that you want to use to trigger events in the module. This value is determined by the control method. For MIDI control data, the control number should be used, and for MIDI pitch data, the MIDI pitch number should be used. For the console metronome, four values are needed - measure number, beat number, division number, and division type. For the console clock, three values are needed - hour, minute, and second. See the following section - ‘Controlling the Score Module with the Score’ for more.
- Repeat On/Off toggle - used to determine whether you want the event messages to be repeated. Turning this on will cause the event values to repeatedly come out at the interval set by parameter 10.
- Repeat Delay Time - A value, in seconds, of the time between repeats. The default, 0.01, states that the event messages would repeat every 10 milliseconds until the repeat toggle is turned off.
- Event Delay On/Off toggle - When turned on, the beginning of the event will be delayed by the time determined in parameter 12.
- Event Delay Time - A value, in seconds, of the time between the ‘Next Event’ button being pressed, and the beginning of the event automation messages.
- Reload Score - If you modify the score while the module is open, the modifications will need to be reloaded manually in order for them to take effect. Pressing this button will reload the score with all of your saved modifications.
Along with these parameters, the following information is displayed in the module:
- Score Name - This is a display of the currently loaded score. It appears immediately above the “Next Event” button.
- Current Event # - This displays the last event that was triggered. This display can be found immediately below the Skip To Event number boxes.
Controlling the Score Automator Module with Scores
You may very well find yourself wanting to script an entire performance with a score, and you may want to design it in such a way that everything occurs automatically, without your interference.
In fact, the Score Automator is designed with this such function in mind. Triggering events with the console metronome or console clock is a great way to make sure that automation occurs exactly how you want it to, exactly when you want it to, every time you perform a work.
But how would someone go about setting new metronome points for each score event? You could, as an option, use the metronome automator to trigger each event in your score, but this might seem less than elegant. Similarly, what if you want a certain event to trigger at minute one, and another event to trigger at minute two?
Thankfully, Score Modules are just like any other module in MSDP, and their parameters can be changed via automation messages pointed to their parameter IDs! If you include parameter changes to the control options in a score’s module, then you can set up the next event directly from the current event. Let’s look at how this should be done with an example.
Observe the score above. It includes 5 events, 0-4. The zeroth event will trigger automatically when the score loads, so this sets up the events to follow.
There are three modules that this score will be controlling - a Chorus module with the id ‘chorusModule’, the Score Automator module containing the score, with the id ‘scoreModule’ - and at one point, another score module containing another score: ‘scoreModule2’.
The starting event sets the chorusModule to listen to Mic 1 as it’s input address (p1), and sets the volume (p3) to 0.
On line 2 of the score, we begin sending information directly to the module containing the score. Control mode is parameter 7, so if you want, you may set the control mode by accessing p7 and setting the number based on the index of the control mode menu. Using this method, index 0 is ‘ctrl’, index 1 is ‘pitch’, 2 is ‘metronome’, and 3 is ‘clock’. Since we set p7 to a value of 2 on line 2, this means that we’ve set our first event to trigger with the metronome.
On line 3 we do the exact same thing, with some different syntax. If you prefer to write out the name of the control mode, you can use the special parameter name - ‘ctrlMode’. The Score Automator includes a variety of special parameter names - setEvent, trigger, ctrlMode, and ctrlValue. We’ll look at how all of these are used in this score.
Line 3 uses the ‘ctrlMode’ to set the mode based on the name of the value, instead of the index number. By writing out ‘metronome’ as the value for ‘ctrlMode’, we can set the control mode without having the index memorized. The other options are ‘ctrl’, ‘pitch’, ‘metronome’, and ‘clock’. There is no inherent advantage to using this method, it’s just available for people who prefer to think this way.
Line 4 uses the ‘ctrlValue’ key to set the value for the metronome event trigger. We know that this requires four values - the measure number, the beat number, the beat division number, and the beat division type. The first three values are input as numbers, while the fourth value is the division type written out - either ‘eighth’, ‘triplet’, ‘sixteenth’, or ‘custom’. ‘Custom’ utilizes the custom beat division defined by the user on the console metronome. This can be used to get extremely granular control over the divisions of time that are used.
The example on line 4 says that when the metronome reaches measure 1, beat 3, subdivision 1, with the subdivision defined in eighth notes, event ‘1’ will be triggered.
Event 1 is brief in comparison. On line six we start a ramp that brings the volume up on the chorus module, and set the chorus rate to 100hz.
Line 7 combines both the ‘ctrlMode’ and ‘ctrlValue’ keys onto a single line. Note that, in this example, we don’t really need to set the control mode again, as we set it to ‘metronome’ in the previous event. You only actually need to set the control mode when you want to change it from it’s current value. This is done in the example above just to demonstrate that multiple parameters can be modified on a single line. In the second part of that message, we are updating the metronome trigger time to trigger the next event at: measure 3, beat 2, subdivision 2 in triplet time. This will set event 2 to begin at that point in time.
Event 2 is also brief. On line 9, we update the values in the chorus module again, ramping the volume back down to zero and updating the rate value again.
On line 10, we set the next event to be triggered by the console clock, by setting the value for ‘ctrlMode’ to ‘clock’. With the clock we only need three values - the hour number, minute number, and second number. On this line, we are setting event ‘3’ to start at hour 0, minute 2, second 12.
Event 3 has several interesting parameter messages happening.
On line 13, we start to point to another Score Module, this one with the ID: ‘scoreModule2’. Pointing to other score modules within a score is a great way to synchronize events occurring across multiple scores in your project.
Line 13 uses the ‘setEvent’ parameter to queue up event 10 in the second score module. Queuing up the event does NOT cause the event to begin. For this, we need to use the ‘trigger’ message.
Line 14 uses the ‘trigger’ message, but sends it to ScoreModule2. This will begin event ‘10’ in the second score, which we queued up on line 13.
Line 15 then sends the trigger message to itself - BUT - it includes an additional value. The trigger message includes an optional delay time, measured in milliseconds. This is another way to make sure that events trigger at just the right time. 10000 milliseconds is the same as 10 seconds. By sending a trigger message back to the Score Module containing the current score, we’ve set the next event, event 4, to begin precisely 10 seconds after event 3 is triggered. Not setting a trigger delay will cause the next event to begin immediately.
As can be seen, setting up the next event within the score itself is a great way to create fully automated, complex scores that can allow an entire musical performance to unfold without any manual involvement by a human.