Link Search Menu Expand Document

Gorilla Script Reference

Introduction

Examples

Reference

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. in 1 + 2 * 3 the 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) * 3 would 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 as exp(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 as 20 * 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 as slider_position ^ 2. See prop_squared.
If you have (for example) a value in seconds or Hertz in the script and want to use it to set a parameter using set_module_param(), then as the parameter is non-linear the script will need to perform a conversion. Sometimes the easiest way to do this is to prepare a lookup table in a spreadsheet and include it as an array in the script. For adjusting volumes set_vol() can be useful as it accepts values in decibels.

Script optimization tips

Here are some general tips on how to make scripts run as fast as possible:
  • Use inc(x) and dec(x) rather than x = x + 1.
  • Try to avoid storing temporary values.
    e.g. use a = 3 * x + 1 instead of a = 3 * x followed by a = a + 1.
  • Consider breaking up long if statements.
    e.g. use if a = b and then if b < 10 rather than if a = b and b > 10 so 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_VEL will 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 on
Note 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 on
Then, 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 on
When 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 on
Alternative 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 on
For 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 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

minMinimum value to return.
maxMaximum 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

realValueThe floating-point value.
decimalPlacesThe 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

sizeNumber of values to store in the array.
minMinimum value.
maxMaximum value.
scalingThe 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

maxThe property value varies linearly between 0 and max.
dBmaxThe 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

maxThe value received by the script when the property is at its maximum value.
displayMin1000 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.
displayMax1000 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

minMinimum value.
maxMaximum value.
scalingThe 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

minMinimum value in script.
maxMaximum value in script.
minMinimum value displayed to user.
maxMaximum 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

groupThe 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

propertyThe 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

propertyThe prop_waveform to display waveforms played in the group.
groupThe group index (counting from 0).

set_prop_param(property, param, value)

Configure various parameters associated with the property.

Arguments

propertyThe property to configure.
paramPROP_MIDI_CC (MIDI controller assigned to the property), PROP_METER_HISTORY or PROP_SET_BY.
valueMIDI 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

propertyThe property to configure.
paramOne of the following:
  • PROP_NAME (name to display to the user. If not set, the property name is used with any underscore characters replaced by spaces).
  • PROP_UNITS (units to be displayed after the value, default is no units).
  • PROP_VALUE_TEXT (custom text to be displayed instead of the value and units).
  • PROP_GROUP (name of a group to include this property in, e.g. for Reason's automation menu).
  • PROP_METADATA (additional info about the parameter for the UI or plugin to use).
  • PROP_REMOTE_ID (text to use as the internal_name in the remote chart in Rack Extensions).
"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

propertyThe prop_waveform to update.
groupThe group to search for a waveform. Use negative values to search in a Mapping instead.
keyThe MIDI key number to search at in the group or mapping.
velThe 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

moduleOne of the following...
  • M_INST (the instrument module).
  • M_GROUP plus the group (counting from 0).
  • M_VGROUP plus the voice group (0 for the "Instrument Voices" group).
  • M_BUS plus the effect bus (counting from 1).
  • M_MAPPING plus the mapping (counting from 1).
  • M_MIDI plus the MIDI file number (counting from 1).
  • M_DATA plus the data file number (counting from 1).
  • M_SCRIPT plus the script number (counting from 1).
subModuleOne of the following...
  • 0 (none)
  • M_COND plus the trigger condition (counting from 1) in the specified group.
  • M_MOD_SRC plus the modulation source (counting from 1) in the specified group.
  • M_FILTER plus the filter/effect slot (counting from 1) in the specified group.
  • M_ZONE plus the zone (counting from 1) in the specified group.
  • M_EFFECT plus the effect slot (counting from 1) in the specified bus.
modRoutingOne of the following...
  • 0 (none)
  • M_MOD plus the mod routing (counting from 1) in the specified module or submodule.
  • 1024 * paramIndex + moduleIndex, for accessing child modules in general (not just mod routings) where paramIndex is the index of the parameter in the specified module/submodule that holds a list of modules, and moduleIndex is the module in that list (counting from 1).
paramParameter index (usually in the order shown in the Instrument Editor module display, starting with 1).
value
  • For parameters with stepped integer values, specify the exact value.
  • For continuous parameters displayed as sliders in the editor, specify a value from 0 to 1000000 (see Parameter display scaling).
  • For draggable floating point values, specify a value 1000 times the actual value (so a value of 1234 sets the parameter to 1.234).
  • If the parameter is an array of values (e.g. the curve of a Mod Routing module) and the value is also an array, then as many values as are available in either array will be set.

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

</li></ul></td></tr>
effectBusWhich bus to set the effect order for (counting from 1).
effectIndexesAn 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

groupThe group to find the mod routing in (counting from 0).
modRoutingWhich mod routing in the group to edit (counting from 1, not including routings in submodules in the group).
subModuleOne of the following...
  • M_GROUP (the destination is in the group module itself).
  • M_MOD_SRC plus the mod source (counting from 1) in the group.
  • M_FILTER plus the per-voice filter/effect (counting from 1) in the group.
destThe 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).
ampModSet 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

destIDThe event with voices that should get their mod sources reset.
sourceIDThe event to copy mod source states from, or 0 to just retrigger from the start.
maskBit mask of which mod sources in the group should be affected (1=first, 2=second, 4=third, etc.)
retrigSet 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

zoneprop_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

groupWhich group the sample zone is in (counting from 0). Use negative values to access Mappings instead of Groups.
zoneIndexWhich 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

zoneAs 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

zoneAs described in get_sample_length()
indexWhich 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

zoneAs described in get_sample_length()
indexWhich 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

ccController number 0 to 127, or CC_PITCHBEND or CC_AFTERTOUCH.
valueValue 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

channelMIDI Channel. Normally set to EVENT_CHAN.
ccController number 0 to 127.
valueValue (will be multiplied by 127.0/maxValue to create a high resolution value.
maxThe 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

eventThe 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

keyThe key (note number) to play, in the range 0 to 127.
velThe velocity to play, in the range 1 to 127.
startSample start position offset in microseconds (limited to within the Start Mod Range of the Zone).
lengthThe 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

eventThe 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

noteWhich 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

statusStatus byte, optionally including channel.
data1Data byte 1, for example key or CC number.
data2Data 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

eventThe 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

eventThe event to modify.
keyThe 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

eventThe event to modify.
velThe 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

eventThe event to modify.
tuneThe detune amount (1000 per cent, so 100000 per semitone).
relative0 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

eventThe event to modify.
panThe pan position from -1000 (hard left) to 1000 (hard right).
relative0 = 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

eventThe event to modify.
volThe volume to set, in 1/1000ths of a decibel (so -3000 = -3 dB).
relative0 = 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

eventThe event to fade in.
microsecThe 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

eventThe event to fade out.
microsecThe length of the fade out, in 1/1000000ths of a second.
stop0 = 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

eventThe event to fade out. Must be a single event, not ALL_EVENTS or a TAG value.
delay_usecWhat length of the sample to play, in 1/1000000ths of a second, before the fade starts.
fade_usecThe 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

eventThe event to set the parameter value for.
paramOne of the EVENT_PARAM constants.
valueThe 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

arrayThe 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

eventThe event to get the parameter value for.
paramOne 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

eventThe 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

eventThe event to tag.
tagsThe 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

eventThe event to untag. tags = the tag(s) to remove.
tagsThe 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

tagsThe 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

eventThe triggering event.
groupThe 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

eventThe triggering event.
groupThe 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

groupThe group index (counting from 0) or ALL_GROUPS.
loaded0 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

sampleFramessum of values collected fron the hidden Latency parameter of relevant effects.
</pre>

delay(usec)

Delay execution of the current callback by the specified time in microseconds.

Arguments

usecTime 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

msecTime 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

ppqDelay 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

callbackIDThe callback (a value taken from CALLBACK_ID).
andFutureDelaysIf 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

usecTime 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

usecTime in 1/1000000ths of a second.
When the audio output starts or restarts, on controller will be called withe a MIDI all-notes-off message (CC 123). This is a good place to check if the host application's sample rate has also changed.

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

ppqBeat 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

sourceAn array or a numeric value to be copied.
destThe 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

array1The first array.
array2The 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

sourceThe source array and the start index to read from, or a numeric value to fill the destination array with.
destThe destination array and the start index to write data to.
countThe 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

arrayThe array to search.
valueThe 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

arrayThe array to search, with optional start index.
valueThe 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

arrayThe array to search, with optional start index.
countThe 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

arrayThe array to search, with optional start index.
valueThe value to find.
countThe 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

array1The array to search, with optional start index.
array2The 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

arrayThe 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

arrayThe array to sort.
direction0 = 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

arrayThe array to sort.
startWhich array value to start at (0 is the first).
countHow 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

stringThe text string to read.
positionWhich 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:

ChordReturn value
None-1
50
M1
62
73
M74
b55
aug6
m7
m68
m79
mM710
m7b511
dim12
sus213
sus414

Arguments

rootVariable that is set to the chord root note by identify_chord, or to -1 if no chord.
heldKeysArray 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_CHORDinteger value representing the current chord, or zero for none
HOST_CHORD_LENGTHlength in ticks of the current chord, or zero if not known
HOST_CHORD_NEXTinteger 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_SECTIONinteger value representing the current song section type, or zero for none
HOST_SECTION_LENGTHlength in ticks of the current song section, or zero if not known
HOST_SECTION_NEXTinteger value representing the next song section type, or zero for none

The possible values are:

0none / not known
1Intro
2Verse
3Chorus
4Bridge / Break
5Outro / 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

arrayAn array variable in the script.
nameOrIndexThe 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

arrayAn array variable in the script.
nameOrIndexThe 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

stringThe string to search.
substringThe string to find.
startposThe 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

stringThe string to measure the length of.

string_range(string, startpos, length)

Returns part of a longer string.

Arguments

stringThe string to extract a range from.
startposThe start position in the string (counting from zero, or negative values to specify a position relative to the end of the string).
lengthThe 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

nameOrIndexThe 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

trackWhich track of the file to search in, or -1 to combine the events of all tracks.
channel0 to 15, or -1 to search for events with any channel.
startIndexThe event index in the file to start searching at, counting from 0.
commandOne 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
Note Off events always use MIDI_COMMAND_NOTE_OFF, never MIDI_COMMAND_NOTE_ON with velocity set to 0.

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

trackWhich track of the file to search in, or -1 to combine the events of all tracks.
indexThe 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

trackWhich 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

trackWhich 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

indexWhich 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

trackWhich 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

trackWhich track of the file to search in, or -1 to combine the events of all tracks.
tickPosition 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

trackWhich 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

trackWhich 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

trackWhich track of the file to search in, or -1 to combine the events of all tracks.
tickPosition 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

lowKeyLowest key in range.
highKeyHighest key in range (can be the same as lowKey).
colorThe 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

keyKey to provide a name for (0 to 127).
nameName for the key.

set_key_selected(key, selected)

Change the displayed state of a keyswitch key.

Arguments

keyKey number (0 to 127).
selected0 = 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_PPQ
BAR_POS_USEC
BAR_USEC
BEAT_USEC
BUS_CONNECTED
BUS_INDEX

C

CALLBACK_ID
select
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

else
end_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_DEFAULT
KEY_COLOR_INACTIVE
KEY_DOWN[]
KEY_DOWN_OCT[]
KEY_IS_CONTROL

L

load_array(array[], nameOrIndex)
load_midi_file(nameOrIndex)

M

M_BUS
M_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_16
tag_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

var
voices_playing(event)

W

while

Z

zone_slice_length(zone, index)
zone_slice_start(zone, index)