Gorilla Script Reference
Introduction
- Instrument scripts
- Setting up for scripting
- General scripting rules
- Parameter display scaling
- Script optimization tips
Examples
- Simple examples
- Using the Mod Wheel to select which group will play
- Adding a diatonic interval to all notes
- Applying changes only to the last played note
- Applying random pitch steps to the last played note
- Last note on each key gets release trigger
- Play samples to end, ignoring note release
- Each note plays a sequence of notes
- Modifying note events
- Using keyswitches to select mappings
- Sliced loop playback
- Equal power effect mix control
- Calculate exponential values
Reference
- Basics
- Math
- Floating-point math
- Conditional statements
- Properties
- Module parameters
- MIDI controllers
- Note events
- Note parameters
- Modifying multiple note events
- Selecting which groups will play
- Time and tempo
- Song position
- Array utilities
- MIDI files
- Audio output connections (Rack Extensions only)
- Keyboard display (not Rack Extensions)
- Index
Introduction
Instrument scripts
This script reference document contains all scripting functions and parameters for creating advanced sample and synthesis based instruments using Gorilla Instrument Editor.
Instruments can include one or more script modules, allowing you include scripting functions to enhance the functionality of your instrument beyond what's possible with the built-in modules, and expose parameters to the user.
The Gorilla Script language is similar to the NI Kontakt script language. This makes it fairly easy to “convert” sample based Kontakt instruments - many of the Kontakt functions will work without modification.
Setting up for scripting
The example instruments that come with the Gorilla SDK already have script modules in them, but if you have an instrument without one, select the top-level instrument module in the left pane of the editor and insert a script module using the (+) menu.A script is a plain text file which contains a series of statements. The easiest way of creating a script is writing it in a standard text editor (such as Sublime Text) and then saving it as a “.txt” file.
The resulting file can be dragged onto the script module in the instrument. If there are errors in the script, these are highlighted in the Script display, with a description of the error printed on the status line below. Alternatively, script text can be pasted from the clipboard into the script module.
The script cannot be edited in the Script text box. If you need to edit the script, do that in a text editor, save, and then reload the script in the Instrument Editor.
General scripting rules
When you write your script there are some basic rules to consider:- Write each statement on one line each.
If a line is too long to read easily, you can type “...” at the end of the first line and then continue on the following line. The lines are now interpreted as a single statement.
- Use as many line feeds (empty rows) as you like between the statement lines.
- Use as many spaces as you like between the words in the statement.
This is very useful for making indents of various parts of the script, to make it easier to read and follow in the text editor.
- Make sure you don’t accidentally mix upper case and lower case letters in your statements. The names of functions and variables are case sensitive.
- Note that in this document 'value' means a numeric value or any expression that evaluates to a numeric value.
This could be a variable name, indexed array value, function return value, or a mathematical calculation involving a combination of those things.
- All numeric values are 32-bit integers (whole numbers with no decimal places) so calculations involving values above about 2 billion may give wrong results.
- Mathematical operators are applied in the same order as other computer languages such as C/C++ and Javascript.
e.g. in1 + 2 * 3the multiplication is done before the addition so the result is 7. However, parentheses can be used to force the evaluation order (changing the previous example to(1 + 2) * 3would force the addition to be done first so the result is 9).
- Text strings are used as arguments to some functions.
The text should be between straight quote marks (e.g. "my string") and quote marks are not allowed within a string. Special characters are allowed in strings (using UTF-8 encoding) but control characters (tab, newline, etc.) are not.
Parameter display scaling
While most module parameters are linear (a series of equally spaced values such as 0 to 100 %) some have non-linear scaling so the control feels right and spreads the useful values over the whole range of movement. Some examples of non-linear parameters and how to identify them are:- Cutoff frequencies or rates in Hz: Exponential.
The mid value is much smaller than the maximum value, and the displayed value can be calculated asexp(a + b * slider_position)where a and b are constants and slider_position is from 0.0 to 1.0. See prop_exp.
- Envelope times: Exponential, but linear in the bottom 1% of the slider.
This allows zero to be reached. See prop_exp.
- Volume in dB: Cube-law decibels.
The displayed value can be calculated as20 * log10(slider_position ^ 3) + a. See prop_decibels.
- Pre-Delay times, compressor ratios: Square-law.
The mid value is one quarter of the maximum, and can be calculated asslider_position ^ 2. See prop_squared.
Script optimization tips
Here are some general tips on how to make scripts run as fast as possible:- Use
inc(x)anddec(x)rather thanx = x + 1.
- Try to avoid storing temporary values.
e.g. usea = 3 * x + 1instead ofa = 3 * xfollowed bya = a + 1.
- Consider breaking up long if statements.
e.g. useif a = band thenif b < 10rather thanif a = b and b > 10so the second part does not have to be calculated if a does not equal b.
- Check the most likely values first in select statements.
- if x can be used as a shorthand for if x != 0 and is calculated faster.
Another example: while a and not b is shorthand for while a != 0 and b = 0</code>.
- Calculations with constant values like
10 * MAX_VELwill be performed in advance, not while executing the script, so there is no advantage to calculating the resulting value yourself.
- There is no performance penalty to defining and using functions: function code is always inserted inline wherever the function is called.
Examples
Simple examples
Below are a few examples of short scripts, as an introduction to what scripts look like and how they work.Simple script 1
This script simply displays the text Hello World! on the Status line (below the Script text box in the Instrument Editor.
Any statements between on init and end on are performed immediately when the script is loaded.
on init
print("Hello World!")
end on
Simple script 2
In this script we define a variable x and set it to the value 1. We then append the variable to the text value is and display the combined result as value is 1 on the Status line:
on init
var x = 1
print("value is " & x)
end on
Simple script 3
In this script we define a function that should display the value of the variable x after a mathematical calculation.
Further down in the script we call the print function to display the value of x on the Status line:
function print_x print(x) end function on init var x x = 3 * -7 + 100 / 2 print_x 'should print 29 end onNote that the text "should print 29" is a comment in the script. Texts after a single quote mark on a line are always comments.
Simple script 4
In this script we define a variable x and set it to the value 1.
We then demonstrate using the conditions if, else and while, and the function inc() to increase the value of x for as long as the while condition is true.
The resulting value x is then displayed on the Status line:
on init
var x = 1
if x > 2
return
else
x = -4 * x + 3
end if
while x < 10
inc(x)
end while
print(x) 'should print 10
end on
Simple script 5
In the previous examples we wanted something to happen when the script started (between on init and end on).
In this example we want something to happen when a MIDI controller value changes, so we put the statements between on controller and end on.
A section of the script starting with on ... and ending with end on is known as a callback. In this script we convert the Mod Wheel data to Sustain Pedal data:
on controller
if EVENT_CC = 1 'convert mod wheel to sustain pedal
set_controller(64, CC[1])
ignore_controller() 'do not change the mod wheel too
end if
end on
Using the Mod Wheel to select which group will play
First in the on note callback, all groups are disabled. Then, only one group is enabled depending on the Mod Wheel position.Mod Wheel values 0 to 127 are divided by 32 to give values in the range 0 to 3 (you will need an instrument with multiple groups to hear the effect of this script):
on note
group_off(EVENT_ID, ALL_GROUPS)
group_on(EVENT_ID, CC[1] / 32)
print("Playing group " & CC[1] / 32)
end on
Adding a diatonic interval to all notes
In on init we set up an array of values - the number of semitones to transpose each of the 12 notes of the octave:on init var interval[12] = (4,4,3,4,3,4,3,4,3,3,4,3) end onThen, for each note received in on note we trigger an additional note using the new_note() function. The additional notes are the same as the incoming notes, except transposed according to the array value for that note. (mod 12 is used for converting the MIDI key number to the octave note number 0 to 11):
on note new_note(EVENT_KEY + interval[EVENT_KEY mod 12], EVENT_VEL, 0, -1) end on
Applying changes only to the last played note
In on init we declare a variable to store the event ID of the last note that was played, and update that value in on note and on release:on init var lastNote = -1 'no event end on on note lastNote = EVENT_ID end on on release lastNote = 0 end onWhen the Mod Wheel (CC 1) moves, we adjust the tuning of the last played note. If no note event with that ID is found (i.e. the note was released and has finished playing) then set_tune has no effect:
on controller
if EVENT_CC = 1 and lastNote
set_tune(lastNote, 1575 * CC[1], 0)
end if
end on
Applying random pitch steps to the last played note
While this example could be achieved more simply with an LFO, to produce random pitch steps, it is a good demonstration of how the delay() function can be used.Each new note first sets the value of lastCallback to the unique ID for that particular callback. Then, until another note arrives and changes the value of lastCallback, the tuning of the note event is adjusted to a random value for every eighth-note (480 ppq).
Why is CALLBACK_ID used instead of EVENT_ID? So this example could be expanded to use the end_delay() function to stop a delay earlier than its scheduled time.
on init
var lastCallback
end on
on note
'changed by each new note
lastCallback = CALLBACK_ID
'random tuning every 8th note
while lastCallback = CALLBACK_ID
delay_ppq(480)
set_tune(EVENT_ID, 100000 * random(-12, 12), 0)
end while
'back to original tuning
set_tune(EVENT_ID, 0, 0)
end on
Last note on each key gets release trigger
When a note is played multiple times with the sustain pedal held, voices can stack up so when the pedal is lifted multiple release-triggered samples are played at the same time.The following script keeps track of the last note played on each key and only enables the release trigger group for that note:
on init
var lastKeyEvent[128]
end on
on note
lastKeyEvent[EVENT_KEY] = EVENT_ID
end on
on release
if lastKeyEvent[EVENT_KEY] != EVENT_ID 'if not last note on key
group_off(EVENT_ID, MyReleaseNoiseGroup) 'switch off group
end if
end on
Play samples to end, ignoring note release
Like an old drum machine, note releases are ignored so the sound keeps playing, but playing the same note again cuts it off and retriggers it.on init var lastEventOnKey[128] = -1 '-1 is never an EVENT_ID end on on note release_note(lastEventOnKey[EVENT_KEY]) 'release the previous note on this key end on on release ignore_event(EVENT_ID) 'don't release this note yet lastEventOnKey[EVENT_KEY] = EVENT_ID 'but store it's ID to release later end onAlternative version where previous notes are not cut off (but Voice Group settings could be used for that):
on note ignore_event(EVENT_ID) new_note(EVENT_KEY, EVENT_VEL, 0, -2) '-2 specifies a one-shot trigger end on
Each note plays a sequence of notes
This example uses the technique of ignoring a note event so it does not trigger any voices, but instead use the on note callback to trigger a sequence of new notes.An array is used to hold an event ID for each key, which is needed to keep track of the notes that have been triggered and will later need releasing.
on init 'current note event for each key var id[128] end onFor as long as the original note event is held, a new note is triggered. Then, after a quarter-note delay (960 ppq) it is released and the while condition repeats to trigger another new note.
This example could be modified to play a specific sequence rather than just repeating the initial note:
on note
'not playing this event, just using it to know how long the key is held
ignore_event(EVENT_ID)
while EVENT_HELD
id[EVENT_KEY] = new_note(EVENT_KEY, EVENT_VEL, 0, 0)
delay_ppq(960)
release_note(id[EVENT_KEY])
end while
end on
Modifying note events
This example declares some properties, which appear as user-editable controls in the instrument script module and later as editable parameters of the instrument. prop_linear declares a property that can be adjusted between the specified minimum and maximum values, so for example when the user edits the Key property, the Key variable will be set to a value in the range -12 to 12.The current property values are applied to each note as it arrives, and for Vol, Pan and Tune, a callback is specified so if the property changes while a note is playing the difference from the old value to the new value is added as a relative offset.
on init prop_linear Key(-12, 12, 1) prop_linear Vel(-100, 100, 1) prop_linear Vol(-20, 20, 1) prop_linear Pan(-1000, 1000, 1) prop_linear Tune(-1200, 1200, 1) var oldVol var oldPan var oldTune end on on note set_key(EVENT_ID, EVENT_KEY + Key) set_vel(EVENT_ID, EVENT_VEL + Vel) set_vol(EVENT_ID, 1000 * Vol, 0) set_pan(EVENT_ID, Pan, 0) set_tune(EVENT_ID, 10 * Tune, 0) end on on Vol set_vol(ALL_EVENTS, 1000 * (Vol - oldVol), 1) oldVol = Vol end on on Pan set_pan(ALL_EVENTS, Pan - oldPan, 1) oldPan = Pan end on on Tune set_tune(ALL_EVENTS, 1000 * (Tune - oldTune), 1) oldTune = Tune end on
Using keyswitches to select mappings
Putting different sets of samples in mappings then selecting which mapping a group should play lets you take full control of articulations and round-robins. This example shows how keyswitches can be scripted to select different mappings. See also EVENT_PARAM_ALT_MAPPING if individual notes need to play different mappings.
'Scripted keyswitches example - switches the mapping played by the first group
on init
const FirstKeyswitch = 48
const LastKeyswitch = 52
set_key_display(FirstKeyswitch, LastKeyswitch, KEY_COLOR_CYAN + KEY_IS_CONTROL)
'also use set_key_name() if targeting NKS or Studio One
var currentKeyswitch = FirstKeyswitch
set_key_selected(currentKeyswitch, 1)
end on
on note
if EVENT_KEY >= FirstKeyswitch and EVENT_KEY <= LastKeyswitch
if currentKeyswitch != EVENT_KEY
'highlight current keyswitch
set_key_selected(currentKeyswitch, 0)
currentKeyswitch = EVENT_KEY
set_key_selected(currentKeyswitch, 1)
'select mapping
set_module_param(M_GROUP+0, 0, 0, 16, currentKeyswitch - FirstKeyswitch + 1) 'Group Alternate Mapping
'don't play a note!
ignore_event(EVENT_ID)
end if
return
end if
end on
Sliced loop playback
When a sample in Recycle, Acid or Apple Loop format is loaded, its original tempo and any transient markers are stored in the Zone the sample is loaded in. An instrument script can access this information to play the individual slices. Ensure the Start Mod Range of the zone is set to the full length of the sample so that playback can start at any startpoint, and use the Group De-Glitch option or scripted fades to avoid clicks.The following example lists the slice positions and lengths for a zone to the debug window of the editor. See the Sliced Loop scripting examples in the SDK for actual playback.
on init
var zone = -1000000 + 1 'a zone ID (mapping 1, zone 1 in this case) or a prop_waveform
var slice
var slicePos
var sliceLen = 1
while sliceLen 'zero if no more slices
slicePos = zone_slice_start(zone, slice)
sliceLen = zone_slice_length(zone, slice)
print("Slice " & slice & ": " & sliceLen & "us @ " & slicePos)
inc(slice)
end while
end on
Equal power effect mix control
Many effect modules have separate wet and dry levels rather than a wet/dry mix. The following script shows how to create a mix control that applies an equal power crossfade between an effect's wet and dry outputs:on init prop_linear Reverb_Mix(0, 1000, 10) set_prop_param(Reverb_Mix, PROP_UNITS, "%") var wet var dry end on function WetDryEqualPower 'convert wet (0 to 1000) to effect wet & dry levels dry = ((321000 + 679 * wet) * wet) / 1000000 dry = 1000000 - dry * dry wet = 1000 - wet wet = ((321000 + 679 * wet) * wet) / 1000000 wet = 1000000 - wet * wet end function on Reverb_Mix 'assumes a Convolution effect in slot 1 of bus 1 wet = Reverb_Mix WetDryEqualPower set_module_param(M_BUS+1, M_EFFECT+1, 0, 7, dry); set_module_param(M_BUS+1, M_EFFECT+1, 0, 8, wet); end on
Or for a DJ-style crossfade where both signals are at full volume in the middle:
function DJCrossfade 'convert wet (0 to 1000) to wet & dry levels
wet = wet - 500
if wet < 0
dry = 1000000
wet = 1000000 - 4 * wet * wet
else
dry = 1000000 - 4 * wet * wet
wet = 1000000
end if
end function
Calculate exponential values
The following script function converts a linearly increasing value to an exponentially increasing value, which may be useful in some calculations:function pow2 'converts x to 1000 * 2 ^ (x / 1000) 'so the returned value doubles each time x increases by 1000 temp = x mod 1000 x = (1000 + temp + ((temp - 1000) * temp) / 2980) << (x / 1000) end function on init var x 'declare the variables used by pow2 function var temp ' end on
And a slightly more efficient version using a scaling factor of 1000 instead of 1024:
function pow2 'converts x to 1024 * 2 ^ (x / 1024) 'so the returned value doubles each time x increases by 1024 temp = x .and. 1023 x = (1024 + temp + ((temp - 1024) * temp) / 3012) << (x >> 10) end function
Here is an approximation for converting a linearly increasing value to a logarithmically increasing value:
function log2
'converts x to 1024 * log2(x / 1024)
'so the value increases by 1024 each time x doubles
temp = 0
if x < 1024
if x < 1
return -10240 'too small
end if
while x < 1024
x = x << 1
dec(temp)
end while
else
while x >= 2048
x = x >> 1
inc(temp)
end while
end if
x = (temp << 10) + 3496 - 8642112 / (x + 1448)
end function
Basics
on init ... end on
Called when the script is loaded, which always happens after the rest of the instrument is loaded. Here you can declare variables and perform any other setup required by the script.Example
on init
print ("Hello World")
end on
var <name>
Declare a variable for storing a numeric value. All variables used in the script must be declared in on init. Each variable can be a single value or an array containing a series of values, and initial value(s) can be provided.Alternatively, variables that have a name ending with $, or are initialized with a text string can be used to store text instead of numeric values.
Limitations
Only use in on init.
Variable names must start with a letter, and contain only letters, numbers and underscore characters ( _ ). Names of existing script functions, variables or constants cannot be used. It's good practice to start variable names with a lower-case letter.
If initial values are provided for an array but there are not enough values to fill the array, the rest of the array will be set to the last initializer value.
An array of numeric values can also be created by specifying the name of a data file module in the instrument instead of a size. The array then directly reads and writes the data in the data file module. If the module is deleted its data is still used by the array until the script is reloaded.
Empty strings have a value of zero in conditional statements. Strings can be compared to other strings using =, !=, etc.
Examples
var x 'create a variable called x, initial value is 0 var y = 1 'create a variable called y, initial value is 1 var z = 0xFF 'create a variable called z, initial value is 255 (FF in hexadecimal) var a[3] 'create an array that holds 3 values called a[0], a[1], a[2] var b[4] = (10, 20, 30, 40) 'create an array and set initial values var c["My Data"] 'create an array that reads and writes to the data in the "My Data" Data File module var myString$ 'create a variable for storing a text string var myString = "Hello" 'create a variable for storing text with an intial text string var myString$[10] 'create an array for storing multiple text strings var myString[2] = ( "one", "two" ) 'create a variable for storing text with initial text strings
const <name>
Declare a variable with a constant (read-only) value. This is useful for giving a name to values that are used throughout a script.Limitations
Only use in on init.
Constant names must start with a letter, and contain only letters, numbers and underscore characters ( _ ). Names of existing script functions, variables or constants cannot be used. It's good practice to make constant names start with an uppercase letter or be all uppercase.
Examples
const MAX_VEL = 127 var velCurve[MAX_VEL + 1] var i = 0 while i <= MAX_VEL velCurve[i] = i * i inc(i) end while
print("message")
Print a message to the status line and debug window in Gorilla Editor. On macOS the text is also sent to any attached debugger (including Recon Tools > Inspect device log when running in Recon). On Windows the Microsoft DebugView will receive the text (e.g. via your DAW) if run as administrator.Limitations
The message to be printed must be placed between straight quotes (""). Other types of quotes (“”). cannot be used.
The message must be printable as text or a numeric value - so while variables and expressions resulting in a numeric value can be printed, array variables cannot unless an array index is provided to select which value in the array to print.
Examples
print("Hello")
print(3)
print(x) 'prints the current value of the variable x
print_active_events()
Print a list of active script events to the debug window in the Instrument Editor. This should only be done while debugging and never in a released product because printing the list may be slow!&
Joins two text strings or numeric values (or expressions that evaluate to a numeric value) to create a single text string. Useful for the print() function.Examples
on init
var x = 3
print("Value of x is " & x)
end on
on note
print("Key " & EVENT_KEY & ", velocity " & EVENT_VEL)
end on
function <name> ... end function
Declare a user-defined function. Must be declared outside any callback and before the function is used. Then wherever the function name is placed in the script, the code in the function will be executed. Using functions does not make the script execution slower so feel free to use them instead of repeating the same code in multiple locations in the script.Limitations
Function names must start with a letter, and contain only letters, numbers and underscore characters ( _ ).
Example
function PrintNoteInfo
print("Key " & EVENT_KEY & " held = " & EVENT_HELD)
end function
on note
PrintNoteInfo
end on
on release
PrintNoteInfo
end on
return
Return immediately from the current callback, or return from the current function to wherever it was called from.Example
function MyFunction
if EVENT_KEY > 72
return
end if
print("Key is " & EVENT_KEY) 'only gets here for keys 60 to 72
end function
on note
if EVENT_KEY < 60
return
end if
MyFunction
end on
'
Starts a comment which continues until the end of the line.Example
var x 'this is a comment
{ }
Marks a section of text as a comment. The section can span multiple lines.Example
var x {this is a comment} = 1
;
Ends a statement so another statement can start on the same line.Example
var x = 1; var y = 2 'not a good example – only use ; if it makes the code easier to read!
...
Continue the current statement on the next line – useful for initializing large arrays.Example
var a[20] = ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ...
11, 12, 13, 14, 15, 16, 17, 18, 19, 20 )
Math
=
Equals (assignment, unless used in a conditional statement - see =).Limitations
Has no effect if the value (or result of an expression) on the right of the equals sign cannot be assigned to the variable on the left. For example when it's the name of an array without specifying the array index in square brackets.
Example
x = 10 'set x to 10 x = y 'set x to the value of variable y x = a[0] 'set x to the first value in array a a[1] = x 'set the second value in array a to the value of variable x
+
Add numeric values.Example
x = x + 10
-
Subtract (or negate the following value if not preceded by an expression that evaluates to a numeric value).Examples
x = x - 10 x = -x
*
Multiply values.Example
x = x * 10
/
Divide (result is rounded down to an integer value, discarding any remainder).Limitations
Dividing by zero results in a value of zero.
Example
x = 5 / 2 'result is rounded down to 2
<<
Shift left (doubles the value the specified number of times).Limitations
Shifting by zero or a negative amount has no effect.
Example
x = x << 2 'shifting left by 2 is equivalent to multiplying by 4
>>
Shift right (halves the value the specified number of times, and round down to the next integer value).Limitations
Shifting by zero or a negative amount has no effect.
Example
x = x >> 2 'shifting right by 2 is equivalent to dividing by 4
mod
Modulus (remainder from division).Limitations
Result is zero if either argument is zero.
Example
x = 10 mod 8 '10 divided by 8 is 1 with remainder 2, so x is 2
.and.
Bitwise AND (keep any bits present in both arguments).Example
x = x .and. 1 'only the lowest bit of x is kept
.or.
Bitwise OR (keep any bits present in either argument).Example
x = x .or. 1 'the lowest bit of x is set to 1
.not.
Bitwise NOT (flip all bits in the value).Example
x = .not. x
abs(value)
Returns the absolute value (make negative values positive).Example
x = abs(-10) 'sets x to 10
in_range(value, min, max)
Returns 1 if value is in the range min to max (including min and max), else returns 0.Example
if in_range(x, 10, 20)
print("x is in between 10 and 20")
end if
inc(var)
Increase the value of a variable by 1.Example
x = 10 inc(x) 'x is now 11
dec(var)
Decrease the value of a variable by 1.Example
x = 10 dec(x) 'x is now 9
random(min, max)
Returns a random value in the range min to max.Arguments
| min | Minimum value to return. |
| max | Maximum value to return. |
Limitations
If max is less than min the return value is always min.
Example
x = random(3, 5) 'x has an equal chance of being 3, 4 or 5
Floating-point math
Some calculations are hard to do with only integer values so Gorilla Script has limited support for floating-point numbers. One-line calculations can be made and the resulting value printed or converted back to an integer. It is currently not possible to have floating-point variables or arrays. In addition to standard mathematical operators and functions (+, -, *, /, sin, cos, tan, acos, asin, atan, ceil, round, floor, exp, log, pow, sqrt) the following functions can be used:int_to_real(var)
Convert an integer value to a floating-point value.Example
'convert frequency 20-25000 Hz to filter cutoff parameter 0-1000000 x = real_to_int(int_to_real(140235) * log(int_to_real(x)) - int_to_real(420106))
real_to_int(realValue)
Convert a floating-point value to an integer.real_to_string(realValue, decimalPlaces)
Convert a floating-point value to text so it can be printed.Arguments
| realValue | The floating-point value. |
| decimalPlaces | The number of figures to show after the decimal point. |
Conditional statements
if <expression> ... [else if...] [else...] end if
If the expression evaluates to a non-zero value, execute the following code, else jump to the next "else if" or "else" (if any).Examples
if x 'if x is any value except zero x = 1 'set x to 1 end if if x = 1 and abs(y) >= 10 print "success" else print "failure" end if if x < 3 print "too small" else if x > 6 print "too big" else print "just right" end if
select <expression> ... case <value> [to <value>] ... end select
Execute only the code following the first case that matches the value of the expression.Example
select x
case 1
print "x is one"
case 10
print "x is ten"
case 0 to 100
print "x is anywhere between 0 and 100"
end select
while <expression> ... end while
Execute the following code repeatedly, as long as the expression evaluates to a non-zero value.Example
while(x < 10) inc(x) 'keep doing this while x is less than 10 end while
USE_CODE_IF("definition") ... END_USE_CODE
These statements can be used to enable or disable parts of a script depending on the Script Defines parameter of the Instrument module, which can contain multiple words separated by spaces or commas. For example the following code only prints something if the Script Defines include the word DEBUG:
USE_CODE_IF(DEBUG)
print("print some debugging text")
END_USE_CODE
Changes to the Script Defines are only applied when the script or the whole instrument is reloaded.USE_CODE_IF_NOT("definition") ... END_USE_CODE
As above, but the code is only used if the definition is not included in the Script Defines.=
Test if two values are equal. Can also use ==.Example
if x = 1
print("success")
end if
!=
Test if two values are not equal. Can also use <>.Example
if x != 1
print("success")
end if
<
Test if the left value is less than the right value.Example
if x < 1
print("success")
end if
>
Test if the left value is greater than the right value.Example
if x > 1
print("success")
end if
<=
Test if the left value is less than or equal to the right value.Example
if x <= 1
print("success")
end if
>=
Test if the left value is greater than or equal to the right value.Example
if x >= 1
print("success")
end if
and
Logical AND. Result is non-zero if both arguments are non-zero.Example
if x = 1 and y < 10
print("success")
end if
or
Logical OR. Result is non-zero if either argument is non-zero.Example
if x = 1 or y < 10
print("success")
end if
not
Logical NOT. Result is non-zero if the following argument is zero.Example
if x > 3 and not y
print("success") 'only if x is greater than 3 and y is 0
end if
Properties
prop_array <name>[size](min, max, scaling)
Declare a property for controlling an array of values. The default value is 0 (or the minimum value if the range does not include 0) but optionally initial values can be set.Limitations
Only use in on init.
Array properties can not be automated in plug-in hosts - instead you must expose every individual value as a separate property.
Arguments
| size | Number of values to store in the array. |
| min | Minimum value. |
| max | Maximum value. |
| scaling | The displayed value is the property value divided by scaling. |
Example
prop_array Velocity_Curve[128](1, 127, 1) 'array of 128 values with range 1 to 127 prop_array Pitch_Sequence[16](-1200, 1200, 100) '16 values with range -12.00 and +12.00
prop_boolean <name>
Declare a Boolean property (the value can be either 0 or 1 - usually used as a switch). The default value is 0 but optionally an initial value can be set.Limitations
Only use in on init.
The same rules for variable names apply to property names (as properties are just variables with some extra attributes). In addition, property names should not be longer than 32 characters and must not be the same as any existing name or symbol (including names in the same scope in motherboard_def.lua for Rack Extensions).
Examples
prop_boolean My_Switch prop_boolean Retrigger = 1
prop_decibels <name>(max, dBmax)
Declare a property with a value display in decibels. Intended for controlling the instrument volume or dB level controls in other modules.Limitations
Only use in on init.
Arguments
| max | The property value varies linearly between 0 and max. |
| dBmax | The displayed value varies as cube-law decibels between -inf and dBmax. |
Example
prop_decibels Volume(1000000, 12) 'when value is 1000000 display is "+12.0 dB"
prop_exp <name>(max, displayMin, displayMax)
Declare a property with an exponential display - useful for times, rates and frequencies.The property value seen in the script varies linearly between 0 and max (the default value is 0 but optionally an initial value can be set).
The value displayed to the user ranges from displayMin/1000 to displayMax/1000 with an exponential scale (the midpoint between 10 and 1000 on an exponential scale is 100).
Arguments
| max | The value received by the script when the property is at its maximum value. |
| displayMin | 1000 times the value displayed to the user when the property is at zero. If negative, the value displayed will be 0 when the property is at zero, and -displayMin/1000 when the property is at 1% of its range. |
| displayMax | 1000 times the value displayed to the user when the property is at its maximum value. |
Limitations
Only use in on init.
Examples
prop_exp Cutoff(1000000, 20000, 25000000) = 549000 'cutoff from 20 Hz to 25 kHz, default 1 kHz prop_exp Rate(1000000, 10, 100000) = 500000 'rate from 0.01 to 100 Hz, defaulting to 1 Hz prop_exp Decay(1000000, -10, 16000) 'decay time from 0.0 to 16.0 sec, with 10 ms at 1%
prop_linear <name>(min, max, scaling)
Declare a property with linear scaling between a specified minimum and maximum value. This is the most commonly used type of property as it's good for knobs and sliders. The default value is 0 (or the minimum value if the range does not include 0) but optionally an initial value can be set.Limitations
Only use in on init.
Arguments
| min | Minimum value. |
| max | Maximum value. |
| scaling | The displayed value is the property value divided by scaling. In this way the number of decimal places to be displayed to the user can be controlled, even though the property value itself is always an integer between min and max. |
Examples
prop_linear Mix(0, 100, 1) = 50 'display range 0 to 100 prop_linear Mix(0, 1000, 10) = 500 'display range 0.0 to 100.0 prop_linear Tune(-1200, 1200, 100) 'display range -12.00 to 12.00
prop_meter <name>
Declare a property for displaying a value measured in realtime in a module. Values that can displayed are audio level in an Effect Bus, Pan or Send effect; gain reduction in a Compressor, Limiter or Gate effect, and playback position in a Group, Sample Oscillator or Wavetable Oscillator. A prop_meter can be attached to a AudioMeter effect to display accurate peak level, stereo correlation, or a 10-band spectrum.Use attach_meter() to connect the meter to the module.
Gain reduction meters are linear between 0 dB and inf, with 6 dB at the midpoint.
If an array size of N is added after the property name (see example below) the meter will display separate levels for up to N audio channels (if available). If the property is not declared as an array the meter will show a single value measured from all channels.
To meter the level of a bus that should not be heard such as a sidechain, route the bus output to its own input.
If a 2-channel meter is attached to a sample Oscillator, the first channel shows the current playback position and the second channel shows the Sample Pos parameter value including any modulation.
Limitations
It is not possible to attach more than one meter to the same module.
Examples
'level meter at output of first effect bus prop_meter Level; attach_meter(Level, M_BUS+1, 0) 'stereo level meter at output of third effect bus prop_meter Level[2]; attach_meter(Level, M_BUS+3, 0) 'level or gain reduction meter (as applicable) for first effect in first effect bus prop_meter GR; attach_meter(GR, M_BUS+1, M_EFFECT+1) 'playback position meter for first group prop_meter Pos; attach_meter(Pos, M_GROUP+0, 0)
prop_squared <name>(min, max, displayMin, displayMax)
Declare a property with a square-law display - useful for some delay times and compressor ratios.The property value seen in the script varies linearly between min and max (the default value is 0 but optionally an initial value can be set).
The value displayed to the user ranges from displayMin to displayMax, proportional to the square of the property value (the midpoint between 0 and 100 on a square-law scale is 25).
Arguments
| min | Minimum value in script. |
| max | Maximum value in script. |
| min | Minimum value displayed to user. |
| max | Maximum value displayed to user. |
Limitations
Only use in on init.
Examples
prop_squared Delay(0, 1000000, 0, 25) 'delay from 0.0 to 25.0 ms prop_squared Ratio(0, 1000000, 1, 20) 'ratio from 1.0 to 20.0 prop_squared Bipolar(-1000, 1000, -100, 100) '-100 to 100 with more resolution in the middle
prop_stepped <name>
Declare a property with a number of discrete values that are created by calling add_step(). The default value is 0 but optionally an initial value can be set.Limitations
Only use in on init.
Examples
prop_stepped Speed = 1 add_step(Speed, "Slow") add_step(Speed, "Normal") add_step(Speed, "Fast") set_prop_param(Speed, CONTROL_PAR_MAX_VALUE, 100) 'set total number of steps without providing a name for each
prop_text <name>
Declare a property for displaying or editing a text string. This can be useful for allowing the user to name an item on the GUI and storing the name with the patch.Limitations
Only use in on init.
Examples
prop_text Name 'editable text prop_text Status_Display; set_prop_param(StatusDisplay, PROP_SET_BY, SET_BY_SCRIPT) 'read only
prop_waveform <name>(group)
Declare a property for displaying a waveform.Limitations
Only use in on init.
When waveform overview data is not available (when not enabled in the instrument, or not yet calculated) the sample name is displayed instead of the waveform.
Arguments
| group | The index of the group that automatically updates the display whenever the latest sample played in the group changes, or -1 if you only want the waveform to change when set_waveform() is called. |
Examples
prop_waveform Wave_Display set_waveform(Wave_Display, -1, 60, 100) 'show waveform at key 60 vel 100 in the first mapping
add_step(property, "text")
For use with prop_stepped. Can also be used with prop_boolean to set the display text for the 0 and 1 values.Limitations
Only use in on init.
Arguments
| property | The property to add a step to. |
| "text" | The text to display for the step. |
attach_meter(property, module, submodule)
Set the module to use as a source for a prop_meter.The module and submodule arguments work the same way as set_module_param().
attach_waveform(property, group)
Set the group to use as a source for a prop_waveform.Arguments
| property | The prop_waveform to display waveforms played in the group. |
| group | The group index (counting from 0). |
set_prop_param(property, param, value)
Configure various parameters associated with the property.Arguments
| property | The property to configure. |
| param | PROP_MIDI_CC (MIDI controller assigned to the property), PROP_METER_HISTORY or PROP_SET_BY. |
| value | MIDI CC number, or for PROP_SET_BY a combination of SET_BY flags. |
Limitations
Only use in on init.
For PROP_MIDI_CC the value should be in the range 1 to 119 (or up to 239 for Rack Extensions but not including the following values: 0, 1, 2, 3, 6, 9, 11, 32, 38, 64, 96-101, 120-127).
For PROP_METER_HISTORY the value is the number of history points to display for a meter (Rack Extensions only).
For PROP_SET_BY, the default value is SET_BY_HOST + SET_BY_SONG + SET_BY_PATCH + SET_BY_REMOTE_AUTO, and the property value is received by the script when it is changed by one of those sources. SET_BY_REMOTE_AUTO means that the property can be remote controlled and automated. This is not allowed for properties connected to the back panel of a Rack Extension. Other valid combinations are:
- SET_BY_HOST + SET_BY_SONG (with or without SET_BY_REMOTE_AUTO): As above but the value is not stored in patches so it does not change when a patch is loaded.
- SET_BY_HOST (with or without SET_BY_REMOTE_AUTO): As above but the value is not stored in patches or songs so reverts to the default value when a song is loaded.
- SET_BY_SCRIPT: When the script changes the property value, the value can be displayed on the GUI (maps to rt_owner in Rack Extensions).
- SET_BY_GUI: The property value can be set by GUI controls but the script does not receive the new value (maps to gui_owner in Rack Extensions).
- SET_BY_GUI + SET_BY_SONG: As above, and the value is also saved and recalled with the song.
- SET_BY_GUI + SET_BY_SONG + SET_BY_PATCH: As above, and the value is also saved and recalled with patches.
Examples
'assign CC7 to this property set_prop_param(Volume, PROP_MIDI_CC, 7) 'this is a display, not user editable set_prop_param(My_Display, PROP_SET_BY, SET_BY_SCRIPT) 'do not change when loading patches set_prop_param(Latch, PROP_SET_BY, SET_BY_HOST + SET_BY_SONG + SET_BY_REMOTE_AUTO) 'not available for automation const NOT_AUTOMATED = SET_BY_HOST + SET_BY_SONG + SET_BY_PATCH set_prop_param(Mode, PROP_SET_BY, NOT_AUTOMATED)
set_prop_param(property, param, "text")
Configure various text strings associated with the property.Arguments
| property | The property to configure. |
| param | One of the following:
|
| "text" | The text to set. |
Limitations
Only use in on init.
Examples
set_prop_param(Reso, PROP_NAME, "Resonance") set_prop_param(Reso, PROP_UNITS, "%") set_prop_param(Reso, PROP_GROUP, "Filter")
set_waveform(property, group, key, vel)
Set the waveform to be displayed in a prop_waveform. The waveform is selected by specifying the group (or mapping), key and velocity. If more than one zone is found at that location the first is used. If no zones are found the waveform display is cleared.Arguments
| property | The prop_waveform to update. |
| group | The group to search for a waveform. Use negative values to search in a Mapping instead. |
| key | The MIDI key number to search at in the group or mapping. |
| vel | The velocity to search at in the group or mapping. |
PROP_GROUP
Use with set_prop_param().PROP_METADATA
Use with set_prop_param().PROP_METER_HISTORY
Use with set_prop_param().PROP_MIDI_CC
Use with set_prop_param().PROP_NAME
Use with set_prop_param().PROP_NON_REALTIME
Use with set_prop_param(). Set to 1 for properties that should not be called from the audio thread because they take a long time to complete or set a parameter in a custom module that is not thread-safe or realtime-safe.Limitations
Do not make a non-realtime property automatable because value changes may then arrive from the realtime thread of the host.
The script code can call set_controller(), set_controller_hd(), set_module_param() and pgs_set_key_val() but must not use other script functions, or modify variables that may be being used simultaneously by other script callbacks.
PROP_SET_BY
Use with set_prop_param().PROP_REMOTE_ID
Use with set_prop_param().PROP_UNITS
Use with set_prop_param() to set the units suffix to be displayed after the parameter value.Set the units to "L|R" to create a pan control that displays either L after the value when it is negative and R when it is positive (does not work for Rack Extensions). Other text can be used e.g. "Front|Rear".
PROP_VALUE_TEXT
Use with set_prop_param() to replace the normal value and units display of a property with your own custom text. Must be called in 'on init' to override the initial value display otherwise later calls will have no effect. Does not work for Rack Extensions.SET_BY_HOST
Use with set_prop_param(...PROP_SET_BY...).The property value can be set from outside the script, and the new value is received by the script. Can be combined with SET_BY_PATCH, SET_BY_SONG and SET_BY_REMOTE_AUTO.
SET_BY_SONG
Use with set_prop_param(...PROP_SET_BY...).The property value is stored with the current song and recalled when the song is loaded. Always combine with either SET_BY_HOST or SET_BY_GUI.
SET_BY_PATCH
Use with set_prop_param(...PROP_SET_BY...).The property value is stored in each patch and recalled when a patch is loaded. Always combine with SET_BY_SONG and either SET_BY_HOST or SET_BY_GUI.
SET_BY_REMOTE_AUTO
Use with set_prop_param(...PROP_SET_BY...).The property value can be Remote controlled and set by automation.
Limitations
Do not use for properties connected to the back panel of a Rack Extension.
Always combine with either SET_BY_HOST or SET_BY_GUI.
SET_BY_SCRIPT
Use with set_prop_param(...PROP_SET_BY...). The property value can be set by the script and displayed on the GUI. Do not combine with any other SET_BY values except in two special cases: Meta parameters in AU plugins that may change or be changed by other parameters, and Rack Extension displays that should preserve their value when a different instrument blob is loaded.
SET_BY_GUI
Use with set_prop_param(...PROP_SET_BY...).The property value can be set by controls on the GUI, but the script does not receive the new value. Can be combined with SET_BY_PATCH, SET_BY_SONG and SET_BY_REMOTE_AUTO.
on <property> ... end on
If you want to be notified when a property value changes, create a callback with the property name as shown in the example below.Example
on init
prop_boolean Mute
end on
on mute
print("Mute value changed to " & Mute)
end on
Module parameters
set_module_param(module, subModule, modRouting, param, value)
Set a parameter in one of the modules in the instrument.If you touch a module parameter in the Instrument Editor then copy (Ctrl/Cmd + C) while holding Shift, a set_module_param() command to set the parameter to its current value will be copied to the clipboard. This can save a lot of time working out the correct argument values.
Arguments
| module | One of the following...
|
| subModule | One of the following...
|
| modRouting | One of the following...
|
| param | Parameter index (usually in the order shown in the Instrument Editor module display, starting with 1). |
| value |
|
Limitations
If a module or parameter that does not exist is specified, the call has no effect.
If the value is outside the range of allowed values for the specified module parameter, it is clipped to the minimum or maximum of the range as appropriate.
Setting zone zone parameters in the range "Start" to "Loop End" may have no immediate effect as this requires re-buffering of loaded audio.
Setting invalid array data to some destinations (especially Custom Envelope curves) may lead to malfunctions. Make sure you only set values that were previously copied from the same parameter, or that values being set are in a valid range.
Examples
'set parameter 2 in instrument set_module_param(M_INST, 0, 0, 2, x) 'set parameter 2 of group 0 (groups are counted from 0) set_module_param(M_GROUP+0, 0, 0, 2, x) 'set parameter 2 of trigger condition 1 of group 0 set_module_param(M_GROUP+0, M_COND+1, 0, 2, x) 'set parameter 2 of mod source 1 of group 0 set_module_param(M_GROUP+0, M_MOD_SRC+1, 0, 2, x) 'set parameter 2 of mod routing 3 in mod source 1 of group 0 set_module_param(M_GROUP+0, M_MOD_SRC+1, M_MOD+3, 2, x) 'set parameter 2 of filter/effect 1 of group 0 set_module_param(M_GROUP+0, M_FILTER+1, 0, 2, x) 'set parameter 2 of mod routing 3 in filter/effect 1 of group 0 set_module_param(M_GROUP+0, M_FILTER+1, M_MOD+3, 2, x) 'set parameter 2 of mod routing 1 in group 0 set_module_param(M_GROUP+0, 0, M_MOD+1, 2, x) 'set parameter 2 of zone 3 in mapping 1 set_module_param(M_MAPPING+1, M_ZONE+3, 0, 2, x) 'set parameter 2 of bus 1 set_module_param(M_BUS+1, 0, 0, 2, x) 'set parameter 2 of effect 3 in bus 1 set_module_param(M_BUS+1, M_EFFECT+3, 0, 2, x) 'set bypass parameter of first script set_module_param(M_SCRIPT+1, 0, 0, 1, x) 'fill the curve parameter of mod routing 1 in group 0 from myArray[1000] onwards set_module_param(M_GROUP+0, 0, M_MOD+1, 9, myArray[1000])
set_module_params(module, subModule, modRouting, values[])
Sets all the parameters of a module in the instrument to values from an array.This function works the same way as set_module_param(), but the last argument is an array containing the parameter values to be set. The first value in the array is the number of values, and usually the array values are obtained by calling get_module_params(), possibly in combination with save_array() to save the values permanently in the instrument.
The function returns the number of values that were actually set, so is zero if the specified module does not exist.
find_module_param(module, subModule, modRouting, "name")
Find the index of a parameter in the specified module by searching for the parameter name.This function works the same way as set_module_param(), but the last argument is the name of the parameter to find (case sensitive). For efficiency, call one time in 'on init' and store the result rather than calling repeatedly.
The function returns the parameter index, or -1 if the specified module was not found or if no parameter was found with the specified name. Note that parameters of built-in modules will keep the same index in future versions, but that may not be true for third party custom modules.
get_module_param(module, subModule, modRouting, param, outVar)
Read the value of a parameter in one of the modules of the instrument.This function works the same way as set_module_param(), but the last argument is a variable that receives the value that was read. If the variable is a string then the display text for the parameter's value is written instead of the numeric value. If the variable is an array and the parameter is an array (such as the curve of a Mod Routing, Shaper or module) the parameter's values are read into the array starting at the specified index.
The function returns the number of values read (so is zero if reading fails, for example if the specified module or parameter does not exist.
get_module_params(module, subModule, modRouting, values[])
Read all the parameter values from a module in the instrument (not including child modules such as mod routings).This function works the same way as get_module_param(), but the last argument is an array that is filled with the parameter values that were read. The first value in the array is the number of values so if a later version of the module has more parameters added these will not be set.
The function returns the number of values read (so is zero if reading fails, for example if the specified module does not exist.
set_effect_order(bus, effectIndexes[startPos])
Set in which order the effects in a bus are applied. Note the indexes of the effects in the bus do not change, just the order they are rendered.Arguments
| effectBus | Which bus to set the effect order for (counting from 1). |
| effectIndexes | An array of effect indexes, for example (3,2,1) to reverse the order of the first three effects in the bus. Effects that are included more than one position in the array are only rendered in the first position. Effects in the bus that are not included in the array are rendered after the ones that are included, in their order as shown in the bus. |
Example
on init var orders[18] = ( 1,2,3, 1,3,2, 2,1,3, 2,3,1, 3,1,2, 3,2,1 ) prop_stepped Order add_step(Order, "123") add_step(Order, "132") add_step(Order, "213") add_step(Order, "231") add_step(Order, "312") add_step(Order, "321") end on on Order 'optionally bypass or mute effects here, wait a short time and unmute them afterwards... ' orderCallback = CALLBACK_ID ' delay(100000) 'wait for bypass to fade in ' if orderCallback != CALLBACK_ID 'order changed again while we were in the delay? ' return ' end if set_effect_order(1, orders[3 * Order]) 'first bus: choose from array of possible orders end on
set_mod_dest(group, modRouting, subModule, dest, ampMod)
Set the destination of a mod routing in a group module to any mod dest in the group including mod sources and per-voice filters/effects. This enables a "mod matrix" to be scripted without inserting mod routings at every possible destination.Arguments
| group | The group to find the mod routing in (counting from 0). |
| modRouting | Which mod routing in the group to edit (counting from 1, not including routings in submodules in the group). |
| subModule | One of the following...
|
| dest | The destination in the selected group or submodule (couting from 1, in the same order as displayed in the Dest parameter of a mod routing in that module). |
| ampMod | Set to 0 if the mod source should offset the destination parameter. Set to 1 if the mod source should scale the destination parameter (normally used for volume/level parameters). |
Limitations
Using the wrong ampMod setting for a destination may give unexpected/unwanted results. One reason to use the wrong setting is if a LFO should modulate a volume above and below its parameter setting, instead of just attenuating.
Examples
'set first routing in first group to no destination set_mod_dest(0, 1, M_GROUP, 0, 0) 'set first routing in first group to third mod destination (Tune) of group set_mod_dest(0, 1, M_GROUP, 3, 0) 'set 1st routing in 1st group to 1st mod destination (Volume) of group, in amp mod mode set_mod_dest(0, 1, M_GROUP, 1, 1) 'set 1st routing in 1st group to the 1st mod destination (Intensity) of 1st mod source set_mod_dest(0, 1, M_MOD_SRC+1, 1, 0) 'set 1st routing in 1st group to 2nd mod destination (e.g. Resonance) in 1st filter/effect set_mod_dest(0, 1, M_FILTER+1, 2, 0)
set_mod_sources(destID, sourceID, mask, retrig)
Reset envelopes or LFOs or copy their current state from one note event to another, to allow analog-style triggering.Arguments
| destID | The event with voices that should get their mod sources reset. |
| sourceID | The event to copy mod source states from, or 0 to just retrigger from the start. |
| mask | Bit mask of which mod sources in the group should be affected (1=first, 2=second, 4=third, etc.) |
| retrig | Set to 0 if the mod sources should continue from their current time position rather than going back to the start. |
Limitations
Applies to all voices played by the specified event IDs. Note that voices do not start playing until on note has returned or called a delay function.
Example
on init
var prevEvent
end on
on note
delay(1) 'wait for this event's voice(s) to start playing
set_mod_sources(EVENT_ID, prevEvent, 9, 1) 'copy mod sources 1 and 4 from previous event
prevEvent = EVENT_ID
while EVENT_HELD
delay_ppq(960) 'then every quarternote
set_mod_sources(EVENT_ID, 0, 255, 1) 'retrigger mod sources 1-8
end while
end on
get_num_zones(group)
Returns the number of zones in the specified Group module.Use a negative group value to get the number of zones in an Mapping module.
get_sample_length(zone)
Returns the length of the sample in the specified zone (measured in microseconds) or zero if no sample is found.Arguments
| zone | prop_waveform property that is currently displaying the zone, or 1000000 * groupIndex + zoneIndex (where groupIndex counts from zero or is negative for mapping indexes, and zoneIndex counts from 1). |
get_slice_length(group, zoneIndex)
Returns the Slice Length parameter in the specified sample zone.Slice Length is a length in beats of the whole sample, which is set when importing an audio file containing Recycle, Acid or Apple Loop information and can also be set manually in each zone.
The function returns the slice length value converted to microseconds at the current tempo, or -1 if the specified group or zone does not exist.
Arguments
| group | Which group the sample zone is in (counting from 0). Use negative values to access Mappings instead of Groups. |
| zoneIndex | Which sample zone to read (counting from 1). |
num_slices_zone(zone)
Returns the number of slices in the specified sample zone, or 0 if there are no slices or the zone was not found.Slice positions are imported from audios file containing Recycle, Acid or Apple Loop information.
Arguments
| zone | As described in get_sample_length() |
zone_slice_start(zone, index)
Returns the position in microseconds of the specified slice in the sample, or 0 if there are not that many slices or the zone was not found.Arguments
| zone | As described in get_sample_length() |
| index | Which slice to get the position of, counting from 0. When index equals the number of slices a negative value giving the total length of the sample is returned.</a> |
zone_slice_length(zone, index)
Returns the length of the specified slice in microseconds at the current tempo, or 0 if there are not that many slices in the sample or the zone was not found.Arguments
| zone | As described in get_sample_length() |
| index | Which slice to get the length of, counting from 0</a> |
on mapping_changed ... end on
Called to notify the script when something in a mapping, zone or sample changed, for example a user sample was loaded.FIRST_GROUP_MOD_SOURCE
When using set_module_param() to modify the Source parameter of a Mod Routing, FIRST_GROUP_MOD_SOURCE is the index of the first mod source specific to that Group (i.e. an envelope or LFO). Use of this constant allows your script to stay future-proof if more non-group mod sources are added in a later version, as they will be added before the Group mod sources.M_BUS
Use with set_module_param() and get_module_param().M_COND
Use with set_module_param() and get_module_param().M_DATA
Use with get_module_param().M_SCRIPT
Use with set_module_param() and get_module_param().M_FILTER
Use with set_module_param() and get_module_param().M_GROUP
Use with set_module_param() and get_module_param().M_INST
Use with set_module_param() and get_module_param().M_MAPPING
Use with set_module_param() and get_module_param().M_MIDI
Use with get_module_param().M_SCRIPT
Use with get_module_param().M_MOD
Use with set_module_param() and get_module_param().M_MOD_SRC
Use with set_module_param() and get_module_param().M_VGROUP
Use as the module argument to set_module_param() and get_module_param() to access Voice Group parameters. Note that the maximum polyphony of the Instrument Voices module (M_VGROUP + 0) cannot be increased beyond the value that has been set manually.M_ZONE
Use with set_module_param() and get_module_param().MIDI controllers
on controller ... end on
Called when a MIDI controller value changes.Example
on controller
print("MIDI CC " & EVENT_CC & " = " & CC[EVENT_CC])
end on
on poly_at ... end on
Called when polyphonic after touch is received.Example
on poly_at
print("Poly pressure key " & POLY_AT_KEY & " = " & POLY_AT[POLY_AT_KEY])
end on
on program_change ... end on
Called when a MIDI program change message is received.Example
on program_change
print("Program change " & MIDI_PROGRAM)
end on
ignore_controller()
Ignore the received MIDI controller change - do not update the value for this controller that is seen by modulation routings and trigger conditions in the instrument.Example
on controller
if EVENT_CC = 1 'modwheel
ignore_controller()
end if
end on
set_controller(cc, value)
Set a MIDI controller value. The resulting value will be seen by modulation routings and trigger conditions in the instrument.Arguments
| cc | Controller number 0 to 127, or CC_PITCHBEND or CC_AFTERTOUCH. |
| value | Value in the range 0 to 127 (or -8192 to 8191 for CC_PITCHBEND). |
Example
on controller
if EVENT_CC = 1 'modwheel
set_controller(64, CC[1]) 'convert to sustain pedal
ignore_controller()
end if
end on
set_controller_hd(channel, cc, value, max)
Set a MIDI controller value with high resolution. The resulting value will be seen by modulation routings and trigger conditions in the instrument.Arguments
| channel | MIDI Channel. Normally set to EVENT_CHAN. |
| cc | Controller number 0 to 127. |
| value | Value (will be multiplied by 127.0/maxValue to create a high resolution value. |
| max | The nominal maximum value (would be 127 for normal MIDI CC messages, but can be much higher to increase resolution). |
Examples
set_controller(EVENT_CHAN, 99, 1000000, 1000000) 'set CC99 to high resolution value 127.0 set_controller(EVENT_CHAN, 99, 12700, 12700) 'also sets CC99 to high resolution value 127.0 set_controller(EVENT_CHAN, 99, 500000, 1000000) 'set CC99 to high resolution value 63.5 set_controller(EVENT_CHAN, 99, -500000, 1000000) 'set CC99 to high resolution value -63.5 set_controller(EVENT_CHAN, 99, 2000000, 1000000) 'set CC99 to high resolution value 254.0
CC[]
Read-only array of current MIDI controller values.EVENT_CC
Read-only index of the current MIDI controller whose value is changing in on controller.CC_PITCHBEND
Use with on controller and set_controller().CC_AFTERTOUCH
Use with on controller and set_controller().CC_FIRST_CV (Rack Extension only)
Use with set_controller() and on controller to send and receive CV values.If on controller is called with an EVENT_CC value greater of equal to CC_FIRST_CV, CC[EVENT_CC] is a new value received from CV socket (EVENT_CC - CC_FIRST_CV).
If set_controller() is called with a cc value greater or equal to CC_FIRST_CV it sends the specified value to CV socket number (EVENT_CC - CC_FIRST_CV). Sending a value greater than zero followed immediately by a value of zero outputs a short trigger pulse from the CV socket.
MIDI_PROGRAM
Read-only index of the program being selected in on program_change.POLY_AT[]
Read-only array of the current polyphonic aftertouch value for each key.POLY_AT_KEY
Read-only index of the polyphonic aftertouch key whose value is changing in on poly_at.Note events
on note ... end on
Called when a note event starts (e.g. when a MIDI key is pressed).As soon as on note returns (or a delay function is called within on note) any voices due to start because of the note event or calls to new_note() will start playing. This gives the script a chance to modify those notes before they start, for example with group_off() or set_event_param().
Example
on note
print("key " & EVENT_KEY & ", velocity " & EVENT_VEL)
end on
on release ... end on
Called when a note event ends (e.g. when a MIDI key is released).Example
on release
print("key " & EVENT_KEY & " was released")
end on
ignore_event(event)
Ignore the event that triggered the on note or on release callback.on note: Do not foward the event to any later scripts for processing, and do not trigger any zones.
on release: Do not forward the event to any later scripts, and ignore the release so the note continues.
Arguments
| event | The event to ignore (will always be EVENT_ID). |
Limitations
Only use in on note and on release.
Must be a specific event, not ALL_EVENTS or tagged_events().
Example
on note
if EVENT_KEY < 60
ignore_event(EVENT_ID) 'do not play notes below middle C
end if
end on
KEY_DOWN[0-127]
Read-only array of values indicating which MIDI notes are currently held. KEY_DOWN[60] returns 1 if middle C is held, or 0 if not held.KEY_DOWN_OCT[0-11]
Read-only array of values indicating which notes of the octave are currently held. KEY_DOWN_OCT[0] returns 1 if any C note (that is not set to KEY_IS_CONTROL) is held, or 0 if not held.new_note(key, vel, start, length)
Trigger a new note event with a specified key, velocity, sample start position and length/duration.This function returns the event ID of the new note, which may be needed to adjust and eventually release the note.
Arguments
| key | The key (note number) to play, in the range 0 to 127. |
| vel | The velocity to play, in the range 1 to 127. |
| start | Sample start position offset in microseconds (limited to within the Start Mod Range of the Zone). |
| length | The note length in microseconds, or zero to continue until release_note() is called, or -1 to continue until the parent note (that triggered the callback this note was triggered in) is released, or -2 to play one-shot (skipping envelope sustain stages and automatically releasing when the amp envelope or sample being played has ended). |
Limitations
Do not use in on init.
Invalid or out-of-range arguments will result in no note being played.
Example
on note new_note(EVENT_KEY + 7, EVENT_VEL, 0, -1) 'add a 5th interval to all notes end on
release_note(event)
End a note, as if the MIDI key that triggered the note had been released.Arguments
| event | The event ID. |
Example
on note delay_ppq(960) release_note(EVENT_ID) 'end all notes after one beat end on
select_keyswitch(note)
Select the current keyswitch, in the same way that incoming MIDI notes do. Assumes the instrument includes Groups with Keyswitch conditions.Arguments
| note | Which MIDI note to trigger. |
send_midi_out(status, data1, data2)
Send a MIDI event to the plugin output (if the plugin has a MIDI out).Arguments
| status | Status byte, optionally including channel. |
| data1 | Data byte 1, for example key or CC number. |
| data2 | Data byte 2, for example velocity or CC value. |
Example
on note
send_midi_out(MIDI_COMMAND_NOTE_ON + EVENT_CHAN, EVENT_KEY, EVENT_VEL)
end on
on release
send_midi_out(MIDI_COMMAND_NOTE_OFF + EVENT_CHAN, EVENT_KEY, EVENT_RELEASE_VEL)
end on
on controller
if EVENT_CC < 120 'only forwarding performance controllers
send_midi_out(MIDI_COMMAND_CC + EVENT_CHAN, EVENT_CC, CC[EVENT_CC])
end if
end on
trigger_new_event()
Create a new event, for example when you want to play a sequence that doesn't stop when the note that triggered it is released, or to start a timer without delaying the following code in the current call. Returns the ID of the new event which on new_event will be called with after the current call returns or enters a delay.Example
on note
id = trigger_new_event()
print("triggered new event " & id)
end on
on new_event
print("handle new event " & EVENT_ID)
end on
voices_playing(event)
Returns 1 if the specified note event has voices still sounding, or 0 if it is silent.Arguments
| event | The event ID. |
Limitations
Returns 0 if the event is not an active note event, or was triggered earlier in the same callback (without a delay inbetween) so has not started playing yet. Must be a specific event, not ALL_EVENTS or tagged_events().
Example
on init
var lastNote
end on
on note
if voices_playing(lastNote)
ignore_event(EVENT_ID) 'don't play if previous note is still playing
else
lastNote = EVENT_ID
end if
end on
EVENT_ID
A unique identifier for each event. Set before the associated callback (on note, on controller, etc.) is called, or returned by new_note(), which creates a new note event.Note parameters
set_key(event, key)
Modify the note on the keyboard an event will play.Arguments
| event | The event to modify. |
| key | The key to use for the note (e.g. for deciding which zones should play). |
Limitations
Has no effect if the event has already started playing (Events start playing as soon as the script code returns or enters a delay).
Example
on note set_key(EVENT_ID, EVENT_KEY + 12) 'play an octave higher end on
set_vel(event, vel)
Modify the velocity an event will play.Arguments
| event | The event to modify. |
| vel | The velocity to use for the note (e.g. for deciding which zones should play). |
Limitations
Has no effect if the event has already started playing (Events start playing as soon as the script code returns or enters a delay).
Example
on note set_vel(EVENT_ID, EVENT_VEL + 50) 'play much louder end on
set_tune(event, tune, relative)
Modify the pitch of an event.Arguments
| event | The event to modify. |
| tune | The detune amount (1000 per cent, so 100000 per semitone). |
| relative | 0 to set the tune amount, or 1 to add the tune amount to any previously set tuning. |
Limitations
Applied in addition to any tuning settings or modulation set up in other instrument modules.
Example
on note set_tune(EVENT_ID, 100000, 0) 'pitch up by 1 semitone end on
set_pan(event, pan, relative)
Modify the stereo pan position of an event.Arguments
| event | The event to modify. |
| pan | The pan position from -1000 (hard left) to 1000 (hard right). |
| relative | 0 = set the pan position, 1 = add the pan position as an offset to any previously set pan position. |
Limitations
Applied in addition to to any pan settings and modulation set up in other instrument modules.
Example
on note set_pan(EVENT_ID, random(-1000, 1000)) 'random pan end on
set_vol(event, vol, relative)
Modify the volume of an event.Arguments
| event | The event to modify. |
| vol | The volume to set, in 1/1000ths of a decibel (so -3000 = -3 dB). |
| relative | 0 = set the volume, 1 = add the volume as an offset to any previously set volume. |
Limitations
Applied in addition to any volume settings and modulation set up in other instrument modules.
Example
on note set_vol(EVENT_ID, -12000) 'play 12 dB quieter end on
fade_in(event, microsec)
Fade in all the voices triggered by an event. Normally called in on note before the event starts playing, but can also be called later if the event has been faded out.Arguments
| event | The event to fade in. |
| microsec | The length of the fade in, in 1/1000000ths of a second. |
Limitations
Negative microsec values are treated as 0.
Example
on note fade_in(EVENT_ID, 1000000) 'all notes have a 1 second fade in end on
fade_out(event, microsec, stop)
Fade out all the voices triggered by an event.Arguments
| event | The event to fade out. |
| microsec | The length of the fade out, in 1/1000000ths of a second. |
| stop | 0 = continue playing silently after the fade, 1 = stop all voices at the end of the fade (this saves some CPU load and polyphony if the voices will not need to fade in again later). |
Limitations
Negative microsec values are treated as 0.
Example
on note fade_out(EVENT_ID, 1000000, 1) 'all notes have a 1 second fade out then stop end on
fade_out_after(event, delay_usec, fade_usec)
Fade out and stop the voice (or voices) triggered by an event after the sample position has advanced by the specified time in microseconds. This is useful if you want to play to a specific point in the sample, but the pitch may be modulated so you don't know how long it will take to get to that point.Arguments
| event | The event to fade out. Must be a single event, not ALL_EVENTS or a TAG value. |
| delay_usec | What length of the sample to play, in 1/1000000ths of a second, before the fade starts. |
| fade_usec | The length of the fade out, in 1/1000000ths of a second. |
EVENT_KEY
Read-only value of the MIDI note that triggered the event. Updated before on note and on release are called.EVENT_VEL
Read-only value of the velocity of the MIDI note that triggered the event. Updated before on note and on release are called.EVENT_CHAN
Read-only value of the MIDI channel that triggered the event. For Rack Extensions the channel is 0 for normal notes and 1 for notes triggered by CV/Gate. Only applies to events that are a result of MIDI input.EVENT_HELD
Read-only value of the status of the MIDI key that triggered the event. 1 = still held, 0 = was released. Updated before on note and on release are called.set_event_param(event, param, value)
Modify a parameter associated with an event.Arguments
| event | The event to set the parameter value for. |
| param | One of the EVENT_PARAM constants. |
| value | The value to set. |
Example
on note set_event_param(EVENT_ID, EVENT_PARAM_0, random(0, 1000000)) 'can use value as mod source end on
get_event_ids(array)
Fills the provided array with the event IDs of currently playing note events. Returns the number of events, and writes a zero to the array after the last event ID.Argument
| array | The array to fill with event IDs. |
Limitations
Not all event IDs are written if the array is too small.
get_event_param(event, param)
Returns the value of a parameter associated with an event.Arguments
| event | The event to get the parameter value for. |
| param | One of the EVENT_PARAM constants (see below). |
Limitations
Returns 0 if event is not a currently playing event.
Must be a specific event, not ALL_EVENTS or tagged_events().
Example
on release env = get_event_param(EVENT_ID, EVENT_PARAM_0) 'read value set by an envelope follower 'now do something with the value... end on
get_event_tags(event)
Returns the tag(s) that an event has been marked with using tag_events(). If more than one tag has been set the resulting value is the sum of all the tags.Arguments
| event | The event to get the parameter value for. |
Limitations
Returns 0 if event is not a currently playing event.
Must be a specific event, not ALL_EVENTS or tagged_events().
Example
on release
if get_event_tags(EVENT_ID) == TAG_1
'do something if only tag 1 is set
else if get_event_tags(EVENT_ID) .and. TAG_3
'do something if tag 3 (and maybe other tags) are set
end if
end on
EVENT_PARAM_0 ... EVENT_PARAM_7
Use with set_event_param() for storing a custom value with a note event, which can be read by the script at a later point with get_event_param(), or can be used as a mod source in mod routings within the instrument. It can also be written to by an Envelope Follower module within a Group so the current audio level of a voice can be read by the script. If more than one envelope follower writes to the same event parameter, only the last value written is kept.EVENT_PARAM_ALT_MAPPING
Use with set_event_param() to specify which Mapping module each Group triggered by the event should play. The value is added to the Group's Alternate Mapping value.Limitations
Has no effect if modified after voices triggered by the event have started playing (Events start playing as soon as the script code returns or enters a delay).
Example
on init prop_stepped Mapping add_step(Mapping, "1") add_step(Mapping, "2") add_step(Mapping, "3") add_step(Mapping, "4") end on on note 'add an offset to the Group Alternate Mapping parameter set_event_param(EVENT_ID, EVENT_PARAM_ALT_MAPPING, Mapping) end on
EVENT_PARAM_DELAY
Use with set_event_param() to set a delay in microseconds before voices start to play after they have been triggered. This can be useful for randomizing or "strumming" the timing of notes without having to add small delays in the instrument script. During the delay the voice is using polyphony but modulation and audio rendering is paused.EVENT_PARAM_KEY
Use with get_event_param() to read the key that triggered an event.EVENT_PARAM_NOTE_LENGTH
Use with get_event_param() to read the time in microseconds since the event was triggered.EVENT_PARAM_PAN
Use with get_event_param() to read the current pan of an event.EVENT_PARAM_PLAY_POS
Use with get_event_param() to read the current sample playback position in microseconds. If an event is playing more than one sample, the position in the first sample is returned. Returns -1 if no samples are playing, or the note has just been triggered and no samples started playing yet.EVENT_PARAM_REVERSE
Use with get_event_param() to reverse sample playback by setting the value to 1. If an event triggers more than one sample, all samples will be reversed. Samples that are already reversed in their Zone settings will play forwards.Limitations
Has no effect if modified after voices triggered by the event have started playing (Events start playing as soon as the script code returns or enters a delay). Playback is only possible from regions of the sample that are preloaded in memory. Set the Start Mod Range in each Zone to the full sample length to allow playback from any point in a sample.
EVENT_PARAM_SOURCE
Use with get_event_param(). Returns -1 if the event was triggered by external input, 0 if it was created by the first instrument script, 1 for the second instrument script, and so on. Can be useful if you want to handle the release of incoming MIDI notes differently to the release of notes triggered by new_note().EVENT_PARAM_START_POS
Use with set_event_param() to specify a sample start position offset in microseconds for all voices triggered by the event (up to a maximum set by the Start Mod Range parameter in each zone).Limitations
Has no effect if modified after voices triggered by the event have started playing (Events start playing as soon as the script code returns or enters a delay).
EVENT_PARAM_TUNE
Use with get_event_param() to read the current tuning of an event.EVENT_PARAM_VEL
Use with get_event_param() to read the velocity that triggered an event.EVENT_PARAM_VOL
Use with get_event_param() to read the current volume of an event.EVENT_RELEASE_VEL
Release velocity (range 0 to 127). This value can be read in the on release callback.Limitations
Not all MIDI devices send release velocity, in which case the value will always be 64. Rack Extensions do not receive release velocity.
Modifying multiple note events
ALL_EVENTS
Use with the following functions in place of a specific event ID to apply the function to all currently playing events: release_note(), set_key(), set_vel(), set_tune(), set_pan(), set_vol(), fade_in(), fade_out(), set_event_param(), group_on(), group_off().tag_event(event, tags)
Mark an event so that groups of events with the same tag can be modified together.Arguments
| event | The event to tag. |
| tags | The tag(s) to apply. Must be a combination of TAG_1, TAG_2, TAG_3 ... TAG_16 (TAG values can be combined by addition, or with the .or. operator, e.g. TAG_1 + TAG_2 is equivalent to TAG_1 .or. TAG_2). |
Limitations
Must be a specific event, not ALL_EVENTS or tagged_events().
Example
on note
if EVENT_KEY < 60
tag_event(EVENT_ID, TAG_1) 'tag any notes below middle C
end if
end on
untag_event(event, tags)
Remove tags set by tag_event().Arguments
| event | The event to untag. tags = the tag(s) to remove. |
| tags | The tag(s) to remove. Must be a combination of TAG_1, TAG_2, TAG_3 ... TAG_16 (TAG values can be combined by addition, or with the .or. operator, e.g. TAG_1 + TAG_2 is equivalent to TAG_1 .or. TAG_2). |
Limitations
Must be a specific event, not ALL_EVENTS or tagged_events().
Example
untag_event(event, TAG_1 + TAG_2 + TAG_2 + TAG_4) 'remove the first 4 tags if set
tagged_events(tags)
Use with the following functions in place of a specific event ID, to apply the function to all active events with the specified tag(s): release_note(), set_key(), set_vel(), set_tune(), set_pan(), set_vol(), fade_in(), fade_out(), set_event_param(), group_on(), group_off(). If more than one tag is specified, events with any of those tags are affected.Arguments
| tags | The tag(s) to find matching events for. |
Example
on controller
if EVENT_CC = 1
set_pan(tagged_events(TAG_1), 8 * CC[1]) 'modwheel pans events tagged with TAG_1
end if
end on
TAG_1 ... TAG_16
These constants are used in the functions described above.Selecting which groups will play
group_off(event, group)
Disable a group from being triggered by the current event.Note events created with new_note() inherit the group on/off settings of the note event that triggered the current callback.
Arguments
| event | The triggering event. |
| group | The group to disable (group number, counting from 0), or ALL_GROUPS. |
Limitations
Has no effect if event is not a currently playing event, or the specified group does not exist. Has no effect if called after an event has started playing (Events start playing as soon as the script code returns or enters a delay).
Example
on note group_off(EVENT_ID, ALL_GROUPS) group_on(EVENT_ID, CC[1]/32) 'play only group 0,1,2 or 3 depending on modwheel position end on
group_on(event, group)
Enable a group to be triggered by the current event (initially all groups can be triggered, so group_on() only has an effect after a call to group_off().Arguments
| event | The triggering event. |
| group | The group to enable (group number, counting from 0), or ALL_GROUPS. |
ALL_GROUPS
Use with group_on() and group_off() to enable or disable all groups at once.NUM_GROUPS
Read-only value giving the number of groups in the instrument.find_group(name)
Returns the index of the Group module with the specified name, or -1 if no Group with that name was found. For best performance call this function in on init and store the result in a variable for later use.find_mapping(name)
Returns the index of the Mapping module with the specified name, or zero if no Mapping with that name was found. For best performance call this function in on init and store the result in a variable for later use.find_zone(name)
Returns a zone identifier that can be used as an argument to functions such as num_slices_zone(). The name must exactly match the sample path and filename shown in the zone. Call this function in on init and store the result in a variable for later use.purge_group(group, loaded)
Unload the samples used by a Group if they are not in use by any other Group or Mapping, to reduce memory usage.To do the same thing for Mappings, use the following command to set the "Active" parameter of the Mapping module:
set_module_param(M_MAPPING+mappingIndex, 0, 0, 2, loaded)
Arguments
| group | The group index (counting from 0) or ALL_GROUPS. |
| loaded | 0 if the samples should be unloaded, 1 if they should be loaded. |
Using ALL_GROUPS does not affect the purge settings of individual groups but instead unloads all samples in the instrument. Samples that are then triggered will load and play, unless they are in an individually purged group or inactive mapping. Use purge_group(ALL_GROUPS, -1) to reset the list of samples that have been played and unload them all again. Using purge_group(ALL_GROUPS, 1) resets the list and loads all samples that are not in purged groups or inactive mappings.
Limitations
For Rack Extensions, all samples in the same .blob file are loaded together in memory so this function will not reduce memory usage. It is however possible to split each mapping into a separate .blob file to be loaded and unloaded independently.
Time and tempo
declare_latency(sampleFrames)
Report audio latency to the host application. Some GE effects (currently only Pitch Shift) must delay the audio signal to apply their processing, but because audio routing is flexible and some delays can be ignored (for example before a 100% wet reverb) the total delay of a network of effect cannot be calculated automatically. Instead your script should calculate the value and report it using this function. For more information see examples/Script Examples/Latency.inst.Limitations
Has no effect in Rack Extensions. Instead set the dsp_latency value of each audio output in realtime_controller (e.g. in response to property value changes that can affect the latency).
Arguments
| sampleFrames | sum of values collected fron the hidden Latency parameter of relevant effects. |
delay(usec)
Delay execution of the current callback by the specified time in microseconds.Arguments
| usec | Time in 1/1000000ths of a second. |
Limitations
usec values less than 0 will be treated as 0.
Do not use in on init.
Example
on note 'for every note delay(100000) 'wait 100 ms new_note(EVENT_KEY, EVENT_VEL, 0, -1) 'then add another identical note end on
delay_msec(msec)
Delay execution of the current callback by an approximate time in milliseconds. This is more CPU efficient than delay() and delat_ppq() because the delay won't end in the middle of an audio buffer, so use when the delay time only has to be accurate to the nearest one or two milliseconds.Arguments
| msec | Time in 1/100ths of a second. |
Limitations
usec values less than 0 will be treated as 0.
Do not use in on init.
Example
on note 'for every note delay(100) 'wait ~100 ms 'do something that needs doing but the exact time is not critical end on
delay_ppq(ppq)
Delay execution of the current callback by the specified beat length, in ppq (960 pulses per quarternote).Arguments
| ppq | Delay in ppq. |
Limitations
ppq values less than 0 will be treated as 0.
Do not use in on init.
Example
on note 'for every note delay(240) 'wait one 16th note new_note(EVENT_KEY, EVENT_VEL, 0, -1) 'then add another identical note end on
end_delay(callbackID, andFutureDelays)
Stops the current delay in the specified callback. Script execution continues in that callback from the next statement after the delay.Arguments
| callbackID | The callback (a value taken from CALLBACK_ID). |
| andFutureDelays | If non-zero, any delay or delay_ppq calls in the callback in the future will also be skipped (will have zero delay). |
Limitations
Has no effect if the specified callback no longer exists or is not delayed.
Example
on init var currentCallback end on on note 'for each new note end_delay(currentCallback, 0) 'if previous octave note did not play yet, play it now currentCallback = CALLBACK_ID 'remember this is now the callback with a delay delay(1000000) 'wait 1 second new_note(EVENT_KEY + 12, EVENT_VEL, 0, -1) 'play a note an octave higher end on
set_bar_start(ppq)
Set a custom position (usually SONG_POS_PPQ for the current position) for beat-synced effects to align to. This is particularly useful for aligning e.g. tremolo to a note played when the host transport is stopped. Use a negative ppq value to remove the custom position and allow effects to synchronize to the host-provided bar and beat positions.usec_to_ppq(usec)
Returns an interval in ppq (960ths of a quarternote) equal to the specified time interval in microseconds at the current tempo.Arguments
| usec | Time in 1/1000000ths of a second. |
Limitations
Do not use in on init as the tempo may not yet be known.
usec_to_samples(usec)
Returns the number of samples at the current sample rate equal to the specified time interval in microseconds.Arguments
| usec | Time in 1/1000000ths of a second. |
ppq_to_usec(ppq)
Returns a time interval in microseconds (1/1000000ths of a second) equal to the specified interval in ppq (960ths of a quarternote).Arguments
| ppq | Beat length in ppq. |
Limitations
Do not use in on init as the tempo may not yet be known.
reset_time_usec()
Reset TIME_USEC to zero, to starting measuring from the current time.BAR_USEC
Duration in microseconds of one bar at the current tempo.Limitations
Do not use in on init as the tempo may not yet be known.
BEAT_USEC
Duration in microseconds of one quarternote at the current tempo.Limitations
Do not use in on init as the tempo may not yet be known.
TIME_MSEC
Elapsed time in milliseconds since audio started running (always increasing - doesn't depend on song position). The time is stored as a 32-bit number so the value will jump (wrap around) once every few weeks if you keep the instrument loaded that long.TIME_USEC
Elapsed time in microseconds - similar to TIME_MSEC but sample-accurate if the exact time between two events needs to be measured.CALLBACK_ID
Variable used in the end_delay() function.Song position
on transport ... end on
Called when playback starts or stops.Example
on transport
if not SONG_PLAYING
release_note(ALL_NOTES) 'release all notes when transport stops
end if
end on
SONG_PLAYING
Read-only value: 0 if the transport is stopped, 1 if the transport is playing.Limitations
Do not use in on init as the transport state may not yet be known.
SONG_POS_PPQ
Read-only value: Current transport position, measured in ppq (960 per quarternote). If the transport is stopped the value keeps increasing from the stop position at the current tempo, so it can still be used as a timing reference. Use SONG_PLAYING to detect if the transport is stopped or playing.Limitations
Do not use in on init as the song position may not yet be known.
BAR_POS_USEC
Read-only value: Current position in microseconds in the current bar.Limitations
Do not use in on init as the bar position may not yet be known.
BAR_POS_PPQ
Read-only value: Current position in ppq in the current bar.Limitations
Do not use in on init as the bar position may not yet be known.
TIME_SIG_NUM
Read-only value: Time signature numerator (length of each bar beat, e.g. 4 = quarternote, 8 = 8th note).Limitations
Do not use in on init as the time signature may not yet be known.
TIME_SIG_DEN
Read-only value: Time signature denominator (number of beats in the current bar).Limitations
Do not use in on init as the time signature may not yet be known.
Array utilities
array_copy(source[], dest[])
Copy the contents of the source array into the destination array. If the arrays have different sizes as much data as possible is copied.Arguments
| source | An array or a numeric value to be copied. |
| dest | The array to copy the value(s) into. |
array_equal(array1[], array2[])
Check if two arrays have the same length and contain the same values in the same order. Returns 1 if the arrays have the same length and contents, else 0.Arguments
| array1 | The first array. |
| array2 | The second array. |
Example
var a[3] = (1, 2, 3) var b[3] = (1, 2, 4) var x = array_equal(a, b) 'x is 0 as arrays have different contents
array_fill(source[start1], dest[start2], count)
Copy count values from the source array (starting at index start1) into the destination array (starting at index start2). If the count is bigger than the source or destination as much data as possible is copied. If source is a numeric value instead of an array, that value gets copied to the specified range of dest. The same array can be specified for source and dest and the copied ranges can overlap, allowing the array data to be shifted left or right.Arguments
| source | The source array and the start index to read from, or a numeric value to fill the destination array with. |
| dest | The destination array and the start index to write data to. |
| count | The number of values to copy. |
Examples
array_fill(0, myArray[10], 20) 'fill myArray indexes 10 to 30 with value 0 array_fill(myArray[10], myArray[0], 100) 'shift myArray contents 10 positions to the left array_fill(array1[100], myArray[0], 10) 'copy 10 values starting at array1[100] into myArray
array_find(array[], value)
Find the first occurrence of value in the array. Returns the array index where value was found, or -1 if the value was not found.Arguments
| array | The array to search. |
| value | The value to find. |
Example
var myArray[3] = (1, 2, 3) var x = array_find(myArray, 2) 'x is 1 as 2 was found at array index 1
array_find_max(array[start], count)
Find the maximum value in the array, searching the specified number of values starting at the specified index (or zero if just the array name is given). Returns the maximum value found.Arguments
| array | The array to search, with optional start index. |
| value | The number of values in the array to search. |
Example
var myArray[3] = (7, 8, 9) var x = array_find)_max(myArray, 2) 'x is 8 (the highest of the first 2 values)</div>
array_find_min(array[start], count)
Find the minimum value in the array, searching the specified number of values starting at the specified index (or zero if just the array name is given). Returns the minimum value found.Arguments
| array | The array to search, with optional start index. |
| count | The number of values in the array to search. |
Example
var myArray[3] = (7, 8, 9) var x = array_find_min(myArray[1], 2) 'x is 8 (the lowest of the two values starting at index 1)</div>
array_find_range(array[start], value, count)
Find the first occurrence of value in the array, searching the specified number of values starting at the specified index (or zero if just the array name is given). Returns the array index where the value was found, or -1 if the value was not found.Arguments
| array | The array to search, with optional start index. |
| value | The value to find. |
| count | The number of values in the array to search. |
Example
var myArray[5] = (1, 2, 3, 4, 5) var x = array_find_range(myArray[1], 5, 3) 'x is -1 as the value 5 was not found in the 3 values starting at index 1</div>
array_find_difference(array1[start1], array2[start2])
Find the first difference between two arrays (or two regions of the same array) starting at the specified indexes (or zero if just the array names are given). Returns the index in array1 where the difference was found, or -1 if no differences were found before the end of either array was reached.Arguments
| array1 | The array to search, with optional start index. |
| array2 | The array to compare it to, with optional start index. |
Example
var array[8] = (1, 2, 3, 4, 1, 2, 0, 4) var notes[32] = ( 60, 64, 67, 0 ) var x = array_find_difference(array, array[4]) 'x is 2 as the value at array[2] is different to the value at array[4 + 2] x = array_find_difference(array, notes) 'x is 0 as the value at array[0] is different to the value at notes[0] x = array_find_difference(notes[10], notes[20]) 'x is -1 as no differences were found comparing notes[10] onwards with notes[20] onwards because all the values are zero</div>
array_length(array[])
Returns the number of elements in an array (the array size that was declared when the array was created).Arguments
| array | The array to measure. |
Example
var myArray[10] var x = array_length(myArray) 'sets x to 10
array_sort(array[], direction)
Sort the values stored in the array.Arguments
| array | The array to sort. |
| direction | 0 = sort from lowest to highest, 1 = sort from highest to lowest. A negative value -N means sort the first N values in the array from lowest to highest. |
Example
var myArray[3] = (3, 1, 2) array_sort(myArray, 0) 'myArray now contains (1, 2, 3)
array_sum(array[], start, count)
Sum a range of values stored in an array.Arguments
| array | The array to sort. |
| start | Which array value to start at (0 is the first). |
| count | How many values to add together. |
Example
const ArraySize = 3 var myArray[ArraySize] = (1, 2, 3) print(array_sum(myArray, 0, ArraySize)) 'should print 6
character_code("string", position)
Return the ASCII numeric value of the character at the given position in a string. Returns zero if position is past the end of the string.Arguments
| string | The text string to read. |
| position | Which character in the string to read (0 is the first). |
Example
on init prop_text String end on on String print(character_code(String, 0) 'print first character when string changes end on
identify_chord(root, heldKeys[])
Calculates the nearest matching chord based on an array of held notes:| Chord | Return value |
| None | -1 |
| 5 | 0 |
| M | 1 |
| 6 | 2 |
| 7 | 3 |
| M7 | 4 |
| b5 | 5 |
| aug | 6 |
| m | 7 |
| m6 | 8 |
| m7 | 9 |
| mM7 | 10 |
| m7b5 | 11 |
| dim | 12 |
| sus2 | 13 |
| sus4 | 14 |
Arguments
| root | Variable that is set to the chord root note by identify_chord, or to -1 if no chord. |
| heldKeys | Array of 12 values representing one octave of pitches (C to B). Value 0 means the key is not held. If the chord is ambiguous, notes with higher values are preferred as root. |
Example
var heldKeys[12] = { 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0) 'C major chord
var root
var chord = identify_chord(root, heldKeys) 'now chord is 1 and root is 0
identify_chord_and_bass(root, bass, heldKeys[])
Similar to identify_chord, but also writes the bass note of the held chord to the provided variable.If a note more than a fifth below the other chord notes is played it is used as the bass note, otherwise the bass note is assumed to be the same as the root note.
The heldKeys array is assumed to have a bit set for each octave that key is held in, with higher bits representing lower octaves.
on chord_changed
Called when the host sends chord information to the plugin (only supported by some hosts and plugin formats).The following variables contain the information from the host:
| HOST_CHORD | integer value representing the current chord, or zero for none |
| HOST_CHORD_LENGTH | length in ticks of the current chord, or zero if not known |
| HOST_CHORD_NEXT | integer value representing the next chord, or zero for none |
HOST_CHORD can be used as the heldKeys argument to identify_chord_and_bass() to interpret the chord.
Example
on init
var root
var bass
var mask
end on
on chord_changed
root = HOST_CHORD .and. 15 '0 to 11
bass = (HOST_CHORD >> 8) .and. 15 '0 to 11
mask = (HOST_CHORD >> 16) 'bit set for each held key relative to root key
print("Chord root " & root & ", bass " & bass & ", mask" & mask)
end on
on section_changed
Called when the host sends song section information to the plugin (only supported by some hosts and plugin formats).The following variables contain the information from the host:
| HOST_SECTION | integer value representing the current song section type, or zero for none |
| HOST_SECTION_LENGTH | length in ticks of the current song section, or zero if not known |
| HOST_SECTION_NEXT | integer value representing the next song section type, or zero for none |
The possible values are:
| 0 | none / not known |
| 1 | Intro |
| 2 | Verse |
| 3 | Chorus |
| 4 | Bridge / Break |
| 5 | Outro / Ending |
identify_interval(root, heldKeys[])
Similar to identify_chord(), but returns the interval (range 0 to 23) if one or two pitches are held, otherwise returns -1.load_array(array[], nameOrIndex)
Copy values from a Data File module to a script array.Arguments
| array | An array variable in the script. |
| nameOrIndex | The index of the Data File module in the instrument (counting from zero) or its name. |
Limitations
If the array or the data to be copied are different sizes, the number of values copied is determined by whichever is smaller.
A Data File can contain either numeric or text values. If it contains numeric values it can only be loaded into a numeric array. If it contains text values it can only be loaded into a text array.
save_array(array[], nameOrIndex)
Copy data from a script array to a Data File module.Arguments
| array | An array variable in the script. |
| nameOrIndex | The index of the Data File module in the instrument (counting from zero) or its name. |
Limitations
If the array or the data to be copied are different sizes, the number of values copied is determined by whichever is smaller.
Text arrays can not be saved to a Data File module, even if it already contains text rather than numeric data.
String utilities
string_find(string, substring, startpos)
Find a string or single character in another string. Returns the position of substring (counting from zero) or -1 if the substring was not found.Arguments
| string | The string to search. |
| substring | The string to find. |
| startpos | The position to start searching (counting from zero, or negative values to specify a position relative to the end of the string). |
string_length(string)
Returns the number of characters in a string.Arguments
| string | The string to measure the length of. |
string_range(string, startpos, length)
Returns part of a longer string.Arguments
| string | The string to extract a range from. |
| startpos | The start position in the string (counting from zero, or negative values to specify a position relative to the end of the string). |
| length | The number of characters to extract. |
MIDI files
load_midi_file(nameOrIndex)
Select which MIDI File module in the instrument to use as the source of MIDI data in the instrument script.Note only one MIDI File can be selected at a time, even if there are multiple Script modules in the instrument. The current position in each MIDI File is remembered when switching between files.
Returns the index of the MIDI file, or -1 if the specified file was not found.
Arguments
| nameOrIndex | The name of the MIDI File module, or its number in the instrument (counting from 0). |
mf_find_event(track, channel, startIndex, command)
Find the next event of the specified type in the current MIDI file. Returns the tick position of the event, or -1 if no matching event was found.Arguments
| track | Which track of the file to search in, or -1 to combine the events of all tracks. |
| channel | 0 to 15, or -1 to search for events with any channel. |
| startIndex | The event index in the file to start searching at, counting from 0. |
| command | One of the MIDI_COMMAND_ constants. |
mf_find_event_at(track, channel, tick, command)
Same as mf_find_event() but searches from the specified tick position instead of an event index.mf_get_bar_ticks()
Returns the bar length of the current MIDI file, measured in ticks (taken from the first time signature found in the file).mf_get_byte_one()
Get the value of the first data byte of the current MIDI file event. For note events this is the key (0-127).mf_get_byte_two()
Get the value of the second data byte of the current MIDI file event. For note events this is the velocity (1-127).mf_get_channel()
Get the channel of the current MIDI file event (0-15).mf_get_command()
Get the type of the current MIDI event. The following constants are available to compare the type to:- MIDI_COMMAND_NOTE_ON
- MIDI_COMMAND_NOTE_OFF
- MIDI_COMMAND_CC
- MIDI_COMMAND_POLY_AT
- MIDI_COMMAND_MONO_AT
- MIDI_COMMAND_PITCH_BEND
- MIDI_COMMAND_PROGRAM_CHANGE
mf_get_event(track, index)
Select a specific event in the current MIDI file.Returns the position of the event in ticks, or -1 if the specified event was not found.
Arguments
| track | Which track of the file to search in, or -1 to combine the events of all tracks. |
| index | The event number between 0 and mf_get_num_events(track) - 1 |
mf_get_first(track)
Select the first event in the current MIDI file.Returns the position of the event in ticks, or -1 if no event was found.
Arguments
| track | Which track of the file to search in, or -1 to combine the events of all tracks. |
mf_get_index()
Returns the index of the current MIDI file event.This can be useful to store a position in a MIDI file which can later be recalled using mf_get_event().
mf_get_last(track)
Select the last event in the current MIDI file.Returns the position of the event in ticks, or -1 if no event was found.
Arguments
| track | Which track of the file to search in, or -1 to combine the events of all tracks. |
mf_get_length()
Returns the length of the current MIDI file event in ticks, or 0 if the current event is not a Note On.mf_get_name(index)
Returns the name of the MIDI file, or 0 if there is no MIDI file at that index.Arguments
| index | Which MIDI file in the instrument to read (counting from 0). |
mf_get_next(track)
Select the next event in the current MIDI file, relative to the current position.Returns the position of the event in ticks, or -1 if no event was found.
Arguments
| track | Which track of the file to search in, or -1 to combine the events of all tracks. |
mf_get_next_at(track, tick)
Select the next event in the current MIDI file, relative to the specified position in ticks (i.e. the first event at that tick position or later).Returns the position of the event in ticks, or -1 if no event was not found.
Arguments
| track | Which track of the file to search in, or -1 to combine the events of all tracks. |
| tick | Position in ticks to start search. |
mf_get_num_events(track)
Returns the number of events in the specified track of the current MIDI file.Arguments
| track | Which track of the file to search in, or -1 to combine the events of all tracks. |
mf_get_num_tracks()
Returns the number of tracks in the current MIDI file.mf_get_pos()
Returns the position of the current MIDI file event in ticks.mf_get_prev(track)
Select the previous event in the current MIDI file, relative to the current position.Returns the position of the event in ticks, or -1 if no event was found.
Arguments
| track | Which track of the file to search in, or -1 to combine the events of all tracks. |
mf_get_prev_at(track, tick)
Select the previous event in the current MIDI file, relative to the specified position in ticks (i.e. the last event before that tick position).Returns the position of the event in ticks, or -1 if no event was found.
Arguments
| track | Which track of the file to search in, or -1 to combine the events of all tracks. |
| tick | Position in ticks to start search. |
mf_get_track_idx()
Returns the track of the current MIDI file event, counting from 0.on midi_drag
Called when the user wants to drag MIDI data from the instrument to the host application. In response you should fill the provided MIDI_DRAG_DATA array with a series of tick positions followed by MIDI byte values as shown in the example below.Events written to the array do not have to be strictly sorted by tick position, but avoid overlapping notes on the same key and channel. To end a note, use a note-on message with velocity zero rather than a note-off message unless you want to set a specific note-off velocity.
Limitations
May be called at the same time as other script functions, so be careful not to change the value of any variables those functions could be using.
Not supported in Rack Extensions.
Example
on midi_drag MIDI_DRAG_DATA[0] = 0 'at start tick MIDI_DRAG_DATA[1] = (MIDI_COMMAND_NOTE_ON << 16) + (60 << 8) + 100 'note on, key 60, vel 100 MIDI_DRAG_DATA[2] = 960 'at one quarternote MIDI_DRAG_DATA[3] = (MIDI_COMMAND_NOTE_ON << 16) + (60 << 8) 'note off end on
Audio output connections (Rack Extensions only)
on io_changed ... end on
Called when an audio output is connected or disconnected. Allows an instrument to change its internal audio routing depending on which outputs are being used.Limitations
Currently only supported in Rack Extensions.
Example
on io_changed
print("Output " & BUS_INDEX & " connected = " & BUS_CONNECTED)
end on
BUS_INDEX
Which audio output bus (counting from 1) was connected or disconnected. Updated before on io_changed is called.BUS_CONNECTED
Read-only state of an audio output bus (0 = bus is now disconnected, 1 = bus is now connected). Updated before on io_changed is called.Keyboard display (not Rack Extensions)
set_key_display(lowKey, highKey, color)
Set how a range of keys are displayed on the plug-in GUI or on hardware with key lights.Arguments
| lowKey | Lowest key in range. |
| highKey | Highest key in range (can be the same as lowKey). |
| color | The following colours are available: KEY_COLOR_RED KEY_COLOR_ORANGE KEY_COLOR_LIGHT_ORANGE KEY_COLOR_WARM_YELLOW KEY_COLOR_YELLOW KEY_COLOR_LIME KEY_COLOR_GREEN KEY_COLOR_MINT KEY_COLOR_TURQUOISE KEY_COLOR_CYAN KEY_COLOR_BLUE KEY_COLOR_PLUM KEY_COLOR_VIOLET KEY_COLOR_PURPLE KEY_COLOR_MAGENTA KEY_COLOR_FUCHSIA KEY_COLOR_DEFAULT (playable keys) KEY_COLOR_INACTIVE (disabled keys) Add KEY_IS_CONTROL to the color value if the key(s) are keyswitches. |
Limitations
Requires support in the instrument/UI framework being targeted.
set_key_name(key, "name")
Set a name (up to 8 characters long) for an individual key.Arguments
| key | Key to provide a name for (0 to 127). |
| name | Name for the key. |
set_key_selected(key, selected)
Change the displayed state of a keyswitch key.Arguments
| key | Key number (0 to 127). |
| selected | 0 = not selected, 1 = selected/pressed/active. |
KEY_IS_CONTROL
Use with set_key_display() to indicate which keys are keyswitches.KEY_COLOR_DEFAULT
Use with set_key_display() to set keys to the default color.KEY_COLOR_INACTIVE
Use with set_key_display() to indicate which keys are inactive.Index
Symbols
- (subtract)- (negate)
; (end statement)
!= (not equal)
... (line continuation)
' (comment)
{ } (block comment)
* (multiply)
/ (divide)
& (concatenate)
+ (add)
< (less than)
<< (shift left)
<= (less than or equal)
<> (not equal)
= (assignment)
= (is equal)
== (is equal)
> (greater than)
>= (greater than or equal)
>> (shift right)
A
abs(value)add_step(property, "text")
ALL_EVENTS
ALL_GROUPS
and
.and.
array_copy(source[], dest[])
array_equal(array1[], array2[])
array_fill(source[start1], dest[start2], count)
array_find(array[], value)
array_find_max(array[start], count)
array_find_min(array[start], count)
array_find_range(array[start], value, count)
array_find_difference(array1[start1], array2[start2])
array_length(array[])
array_sort(array[], direction)
array_sum(array[], start, count)
attach_meter(property, module, submodule)
attach_waveform(property, group)
B
BAR_POS_PPQBAR_POS_USEC
BAR_USEC
BEAT_USEC
BUS_CONNECTED
BUS_INDEX
C
CALLBACK_IDselect
CC_AFTERTOUCH
CC_FIRST_CV
CC_PITCHBEND
CC[]
character_code("string", position)
const
D
dec(var)declare_latency(sampleFrames)
delay(usec)
delay_msec(msec)
delay_ppq(ppq)
E
elseend_delay(callbackID, andFutureDelays)
END_USE_CODE
EVENT_CC
EVENT_CHAN
EVENT_HELD
EVENT_ID
EVENT_KEY
EVENT_PARAM_0 ... EVENT_PARAM_7
EVENT_PARAM_ALT_MAPPING
EVENT_PARAM_DELAY
EVENT_PARAM_KEY
EVENT_PARAM_NOTE_LENGTH
EVENT_PARAM_PAN
EVENT_PARAM_PLAY_POS
EVENT_PARAM_REVERSE
EVENT_PARAM_SOURCE
EVENT_PARAM_START_POS
EVENT_PARAM_TUNE
EVENT_PARAM_VEL
EVENT_PARAM_VOL
EVENT_RELEASE_VEL
EVENT_VEL
F
fade_in(event, usec)fade_out(event, usec, stop)
fade_out_after(event, delay_usec, fade_usec)
find_group(name)
find_mapping(name)
find_module_param(module, subModule, modRouting, "name")
find_zone(name)
FIRST_GROUP_MOD_SOURCE
function
G
get_event_ids(array)get_event_param(event, param)
get_event_tags(event)
get_module_param(module, subModule, modRouting, param, outVar)
get_module_params(module, subModule, modRouting, values[])
get_num_zones(group)
get_sample_length(zone)
get_slice_length(group, zoneIndex)
group_off(event, group)
group_on(event, group)
I
identify_chord_and_bass(root, bass, heldKeys[])identify_chord(root, heldKeys[])
identify_interval(root, heldKeys[])
if
ignore_controller()
ignore_event(event)
in_range(value, min, max)
inc(var)
int_to_real(var)
K
KEY_COLOR_DEFAULTKEY_COLOR_INACTIVE
KEY_DOWN[]
KEY_DOWN_OCT[]
KEY_IS_CONTROL
L
load_array(array[], nameOrIndex)load_midi_file(nameOrIndex)
M
M_BUSM_COND
M_DATA
M_EFFECT
M_FILTER
M_GROUP
M_INST
M_MAPPING
M_MIDI
M_MOD
M_MOD_SRC
M_SCRIPT
M_VGROUP
M_ZONE
MIDI_DRAG_DATA
MIDI_PROGRAM
mf_find_event(track, channel, startIndex, command)
mf_find_event_at(track, channel, ticks, command)
mf_get_bar_ticks()
mf_get_byte_one()
mf_get_byte_two()
mf_get_channel()
mf_get_command()
mf_get_event(track, index)
mf_get_first(track)
mf_get_index()
mf_get_last(track)
mf_get_length()
mf_get_name(index)
mf_get_next_at(track, tick)
mf_get_next(track)
mf_get_num_events(track)
mf_get_num_tracks()
mf_get_pos()
mf_get_prev_at(track, tick)
mf_get_prev(track)
mf_get_track_idx()
mod
N
new_note(key, vel, start, length)not
num_slices_zone(zone)
.not.
O
on <property>on chord_changed
on controller
on init
on io_changed
on mapping_changed
on midi_drag
on new_event
on note
on poly_at
on program_change
on release
on section_changed
on transport
or
.or.
P
POLY_AT[]POLY_AT_KEY
ppq_to_usec(ppq)
print("message")
print_active_events()
prop_array <name>[size](min, max, scaling)
prop_boolean <name>
prop_decibels <name>(max, dBmax)
prop_exp <name>(max, displayMin, displayMax)
PROP_GROUP
prop_linear <name>(min, max, scaling)
prop_meter <name>
PROP_METADATA
PROP_METER_HISTORY
PROP_MIDI_CC
PROP_NAME
PROP_NON_REALTIME
PROP_REMOTE_ID
PROP_SET_BY
prop_squared <name>(max, displayMin, displayMax)
prop_stepped <name>
PROP_UNITS
PROP_VALUE_TEXT
prop_waveform <name>(group)
purge_group(group, loaded)
R
random(min, max)real_to_int(realValue)
real_to_string(realValue, decimalPlaces)
release_note(event)
reset_time_usec()
return
S
save_array(array[], nameOrIndex)select
select_keyswitch(note)
send_midi_out(status, data1, data2)
set_bar_start(ppq)
SET_BY_GUI
SET_BY_HOST
SET_BY_PATCH
SET_BY_REMOTE_AUTO
SET_BY_REMOTE_AUTO
SET_BY_SONG
set_controller(cc, value)
set_controller_hd(channel, cc, value, max)
set_effect_order(bus, effectIndexes[])
set_event_param(event, param, value)
set_key_display(lowKey, highKey, color)
set_key_name(key, "name")
set_key_selected(key, selected)
set_key(event, key)
set_mod_dest(group, modRouting, subModule, dest, ampMod)
set_mod_sources(destID, sourceID, mask, retrig)
set_module_param(module, subModule, modRouting, param, value)
set_module_params(module, subModule, modRouting, values[])
set_pan(event, pan, relative)
set_prop_param(property, param, "text")
set_prop_param(property, param, value)
set_tune(event, tune, relative)
set_vel(event, vel)
set_vol(event, vol, relative)
set_waveform(property, group, key, vel)
SONG_PLAYING
SONG_POS_PPQ
string_find(string, substring, startpos)
string_length(string)
string_range(string, startpos, length)
T
TAG_1 ... TAG_16tag_event(event, tags)
tagged_events(tags)
TIME_MSEC
TIME_USEC
TIME_SIG_DEN
TIME_SIG_NUM
trigger_new_event()
U
untag_event(event, tags)USE_CODE_IF_NOT("definition")
USE_CODE_IF("definition")
usec_to_ppq(usec)
usec_to_samples(usec)
V
varvoices_playing(event)
W
whileZ
zone_slice_length(zone, index)zone_slice_start(zone, index)