By request, this will be an overview of how to create a basic script package for Studio One to do some things that can't be accomplished with macros.
If you intend to edit or create these types of packages use a code editor so that it will be easier to read with code highlighting and similar. One good choice is Visual Studio Code which is cross platform and lightweight, but any decent editor will do, Notepad++ or whatever else you prefer.
** This is an undocumented and unofficial "feature" so please treat it as such and don't expect any official support. **
Tutorial Script: The Basics
This tutorial script parses all selected clip names and any clips that have 'vocal' in their name get renamed to "Tutorial'. It's a basic demonstration of selective targeting, the kind of logic not possible with macros. It puts a new action in the Event menu named "Do Something" and it will also appear in the action list as Event | Do Something. The code is fairly well commented for a more complete understanding so it looks longer than it would be otherwise.
Requirements: At a minimum you'll need the three file types described below for a working script package. The package being demonstrated in this post below can be downloaded here.
This file identifies the package. The example below is identified as tutorial.package but the ID can be anything really. The name should be unique to not potentially conflict with other package names. Example: "Package:ID" value="joe.smith.audio.editing"
Every action or new function you want to add to Studio One requires it's own class definition in this file.
Making The Package
To compile a script package for use in Studio One, zip up the files and change the zip file extender to *.package and put it in Studio One's application \scripts folder. Once you get a new action listing in Studio One successfully you can edit the JS code, zip and rename the package again, replace it in the scripts folder again, and test your code changes, without having to restart Studio One.
If you edit the class definitions, like for example changing the action name, you'll have to restart Studio One to see the changes.
A few things to look at, some event or clip properties or methods.
tune [number] audio clips only, testing for null excludes others, avoids potential errors
Basic Selection Filtering
The example code below shows one way to make selections by random criteria. In this example, only selecting clips named "Bass". This code sample assumes "Select All" manually to have all timeline clips selected or firing it in the entry function, that all clips would be initially selected or it only applies to the clips that are currently selected, not all clips on the timeline.
The method being used is to go through all of the items and the ones that match the criteria get added to an array. Then it's deselects everything and then selects all of the items in the array, clips named "Bass", or whatever the filter criteria you choose to use that loads the array.
This allows you to do things like select all clips that are transposed, or muted, or by any other criteria you can parse from object properties. Or with midi notes, select all notes with velocity lower or higher than x, or length shorter or longer than y, etc, etc.
Creating A Basic GUI
There will be times when you may want to use a GUI for your script and in Studio One this is handled via an XML skin. The following will explain how to create a basic GUI for a script.
The first thing you'll need to do is tell the package where the skin.xml file is located. This is done in the metainfo.xml file. The edit of that file is shown below, adding the Package:SkinFile attribute.
Create A Skin Folder & File
Create a folder named \skin in the same folder where your script files are and also create a file named skin.xml inside of the \skin folder. The skin.xml file itself is pretty easy to understand...
2. It allows laying out the UI controls much like designing a web page.
3. The method to create and call an OS window for the form is already built in.
The skin.xml file below is a simple form with one button and one text box. The name of our form below is "testForm". A skin file can contain as many different forms as you need for different functions.
One not so great thing about this is that forms called this way are application modal, which means that they're modal dialogs, that you can't keep them open and at the same time manually operate the main application UI. Not a major deal if you only want to present the user with some choices for performing an edit.
Opening The UI From The JS Code File
To open a GUI from a script you call it directly like shown in the code sample below. The package being targeted for the skin,"tutorial.package", should typically be using a constant but it's literal there to make the code line more understandable for learning.
So the one code line will open the UI / form in it's performEdit() function, Host.GUI.runDialog(). Notice that the other code from the first example is no longer there, it will be somewhere else now.
So now when you fire the action it opens a user interface with a textbox and a button on it. They don't do anything at all yet though. We'll get to that in the next post, editing the JS code file to respond to the button being clicked and to use whatever text you type into the text box.
You can alao use graphic backgrounds and/or your own graphic buttons in a skin, like what you see on some External Device UI's which are also xml skins created the same way.
When of if you do use a GUI, the common convention is to use "..." after the action name to indicate that it calls a dialog, so we should rename our action to "Do Something...".
Linking GUI Controls To JS Code
In order for UI controls to do anything they have to be defined in the JS code file, so we first need to add a parameter observer to the interface list as shown below... IParamObserver.
Now that the JS code knows what those things on the UI are, we can use them. To do that, we create a new function in our main function named this.paramChanged. What that does is run code based on what UI parameter has changed, like clicking the UI button in our sample case. So in this case the code that renames the clips only runs when the button is clicked.
The code that did the parsing and renaming was moved from this.performEdit to this.paramChanged. Also, instead of using the static text "Bass" like we did earlier for matching, it uses whatever you type into the text box. That value is represented as this.editTarget.string, the current value of the text box. Using the same method, instead of replacing everything that matches the filter with "Tutorial" which is hard coded in this example, you could add another edit box to put in any random text to use as the replacement text.
Here's the edited JS code file after all of the changes shown above.
Example: Editing Midi Notes
Some things that may seem complex on the surface are easier than they appear to be. For example, some users asked for a function to reverse a series of selected midi notes. One way to do that (in code there's often more than one way to do something) would be ...
1. Reading the series of notes into an array and their pitches into a second array.
2. Reversing the second array with the JS .reverse() function.
3. Reading back from that reversed array and sequentially assigning the reversed values back to the original note series.
The result is the note pitches being flipped 180 degrees. You could do the same with the note lengths and velocities at the same time. Once you can access and modify the properties of things everything else is just basic logic. Below it's being triggered with a bound key.
Example: Conforming Colors
The example JS code below allows defining RGB colors and conforming track colors by the track names, if a track name contains certain text. It can be expanded to load colors from a file. The basic sample below only targets two names, Bass and Guitar. The idea is to fill in the code with the custom colors you want to use for specific track types and bind it to a key, and whenever you hit that key everything in a song always conforms to your default custom color set.
Basic Outline of Studio One Objects & Functions
(work in progress)
https://docs.google.com/spreadsheets/d/ ... q_/pubhtml
The above should be enough general information to get anyone started with basic scripting in Studio One. Of course, as the goals become more complex, so can the code, and (see Narech's great Studio One X tool) things can potentially get quite a bit more complex code-wise depending on what you want to accomplish.
Having said that, if you just want to make an action to do something you want to do that can't be done with a macro, or perhaps do something you want that nobody else even wants, writing your own script is the best path.
As scripting in general goes (even without any official documentation) doing it in Studio One is easier than doing it in most other audio workstations that allow it. The combination of using JavaScipt and XML as the foundation raises the "accessibility level" quite a bit from say... Python, or Lua ... especially as relates to GUI's.
Have fun, and if you create anything useful please share.
[MOD EDIT - This topic is locked for obvious reasons but wanted to say "Thanks" to Lawrence, GOOD STUFF here.]
Users browsing this forum: No registered users and 5 guests