Mobius Scripting

June, 2007



Contents

1  Introduction
2  Writing Scripts
3  Running Scripts
4  Debugging Scripts
5  Script Language Basics
5.1      Anatomy of a Statement
5.2      Intrinsic and Function Statements
5.3      Case Insensitivity
5.4      Parameters and Variables
5.5      The Mysterious $
6  Script Execution Environment
7  Script Language Reference
7.1      Declarations
7.1.1          !autoload
7.1.2          !controller
7.1.3          !focuslock
7.1.4          !multiclick
7.1.5          !name
7.1.6          !quantize
7.1.7          !spread
7.1.8          !sustain
7.1.9          !switchQuantize
7.2      Expressions
7.3      Intrinsic Statements
7.3.1          break
7.3.2          Call
7.3.3          Cancel
7.3.4          diff
7.3.5          end
7.3.6          endproc
7.3.7          Echo
7.3.8          else
7.3.9          elseif
7.3.10          endif
7.3.11          for
7.3.12          if
7.3.13          InitPreset
7.3.14          Jump
7.3.15          Label
7.3.16          Load
7.3.17          Message
7.3.18          next
7.3.19          Preset
7.3.20          proc
7.3.21          Prompt
7.3.22          repeat
7.3.23          Save
7.3.24          set
7.3.25          Setup
7.3.26          Variable
7.3.27          Wait
7.3.28          while
7.4      Special Labels
7.4.1          reentry
7.4.2          sustain
7.4.3          endSustain
7.4.4          click
7.4.5          endClick
7.5      Functions
7.6      Modes
7.7      Parameters
7.7.1          Global Parameters
7.7.1.1              altFeedbackDisable
7.7.1.2              audioInput
7.7.1.3              audioOutput
7.7.1.4              autoFeedbackReduction
7.7.1.5              driftCheckPoint
7.7.1.6              fadeFrames
7.7.1.7              groupFunctions
7.7.1.8              inputLatency
7.7.1.9              integerWaveFile
7.7.1.10              isolateOverdubs
7.7.1.11              longPress
7.7.1.12              maxSyncDrift
7.7.1.13              midiInput
7.7.1.14              midiMode
7.7.1.15              midiOutput
7.7.1.16              midiRecordPulsed
7.7.1.17              midiThrough
7.7.1.18              monitorAudio
7.7.1.19              muteCancelFunctions
7.7.1.20              noiseFloor
7.7.1.21              outputLatency
7.7.1.22              pedalMode
7.7.1.23              project
7.7.1.24              quickSave
7.7.1.25              trackGroups
7.7.1.26              saveLayers
7.7.1.27              setup
7.7.1.28              traceDebugLevel
7.7.1.29              tracePrintLevel
7.7.1.30              vstMidiInput
7.7.1.31              vstMidiOutput
7.7.1.32              vstMidiThrough
7.7.2          Preset Parameters
7.7.2.1              subCycle
7.7.2.2              autoRecord
7.7.2.3              multiplyMode
7.7.2.4              insertMode
7.7.2.5              shuffleMode
7.7.2.6              interfaceMode
7.7.2.7              loopCopy
7.7.2.8              trackCopy
7.7.2.9              loopCount
7.7.2.10              muteMode
7.7.2.11              muteCancel
7.7.2.12              overdubMode
7.7.2.13              overdubTransfer
7.7.2.14              reverseTransfer
7.7.2.15              rateTransfer
7.7.2.16              pitchTransfer
7.7.2.17              quantize
7.7.2.18              bounceQuantize
7.7.2.19              recordMode
7.7.2.20              roundMode
7.7.2.21              samplerStyle
7.7.2.22              switchQuant
7.7.2.23              timeCopy
7.7.2.24              soundCopy
7.7.2.25              syncMode
7.7.2.26              trackSyncMode
7.7.2.27              unroundedSyncAdjust
7.7.2.28              speedSyncAdjust
7.7.2.29              switchSyncAdjust
7.7.2.30              threshold
7.7.2.31              velocity
7.7.2.32              maxUndo
7.7.2.33              maxRedo
7.7.2.34              minTempo
7.7.2.35              maxTempo
7.7.2.36              recordTempo
7.7.2.37              recordBeats
7.7.2.38              recordBars
7.7.2.39              noFeedbackUndo
7.7.2.40              noLayerFlattening
7.7.2.41              rateSequence
7.7.2.42              rateShiftRetrigger
7.7.2.43              pitchSequence
7.7.2.44              pitchShiftRetrigger
7.7.2.45              slipMode
7.7.2.46              slipTime
7.7.2.47              realignTime
7.7.2.48              outRealignMode
7.7.3          Track Parameters
7.7.3.1              altFeedbackLevel
7.7.3.2              feedbackLevel
7.7.3.3              focus
7.7.3.4              group
7.7.3.5              inputLevel
7.7.3.6              outputLevel
7.7.3.7              pan
7.7.3.8              trackPreset
7.8      System Variables
7.8.1          basePulseFrames
7.8.2          blockFrames
7.8.3          cycleCount
7.8.4          cycleFrame
7.8.5          cycleFrames
7.8.6          cycleNumber
7.8.7          externalPulse
7.8.8          externalPulses
7.8.9          globalMute
7.8.10          inHalfSpeed
7.8.11          inMute
7.8.12          inOverdub
7.8.13          inPause
7.8.14          inRealign
7.8.15          inReturn
7.8.16          inReverse
7.8.17          layerCount
7.8.18          loopCount
7.8.19          loopFrame
7.8.20          loopFrames
7.8.21          loopNumber
7.8.22          mode
7.8.23          nextEvent
7.8.24          nextEventFunction
7.8.25          nextLoop
7.8.26          noExternalAudio
7.8.27          outSyncMaster
7.8.28          preRealignFrame
7.8.29          preRealignPulseFrame
7.8.30          pulseFrame
7.8.31          pulseFrames
7.8.32          pulseLoopFrame
7.8.33          rawPitch
7.8.34          rawRate
7.8.35          recordCyclePulses
7.8.36          returnCode
7.8.37          sampleFrames
7.8.38          scalePitch
7.8.39          scaleRate
7.8.40          solo
7.8.41          subCycleCount
7.8.42          subCycleFrame
7.8.43          subCycleFrames
7.8.44          subCycleNumber
7.8.45          sustainCount
7.8.46          syncBar
7.8.47          syncBeat
7.8.48          syncDrift
7.8.49          syncDriftChecks
7.8.50          syncHostBar
7.8.51          syncHostBeat
7.8.52          syncHostRawBeat
7.8.53          syncHostReceiving
7.8.54          syncHostStarted
7.8.55          syncHostTempo
7.8.56          syncInBar
7.8.57          syncInBeat
7.8.58          syncInRawBeat
7.8.59          syncInReceiving
7.8.60          syncInStarted
7.8.61          syncInTempo
7.8.62          syncOutBar
7.8.63          syncOutBeat
7.8.64          syncOutRawBeat
7.8.65          syncOutSending
7.8.66          syncOutStarted
7.8.67          syncOutStarts
7.8.68          syncOutTempo
7.8.69          syncRawBeat
7.8.70          syncRealigns
7.8.71          tempo
7.8.72          track
7.8.73          trackSyncMaster
8  Examples
8.1      Sustain Scripts
8.2      Long Press Scripts

1 Introduction

Mobius provides a powerful feature called scripts that can be used to add new functions or customize the behavior of Mobius to match your looping style. Some of the things that can be done with scripts are:

A script is simply a text file that can be created with any text editor. The contents of the script file are statements in a language called the Mobius Scripting Language. Once the script files have been written, they are registered so that Mobius knows their names and locations. Once a script file has been registered, it may be assigned one or more triggers which can be MIDI events, computer keyboard presses, or buttons in the Mobius window.

When a trigger for a script is received, the statements in the script are performed. This process is called running the script, executing the script, or calling the script.

The following is an example of a simple script:

  Wait loop
  Reverse
  HalfSpeed

When this script is called, it will first wait until the loop reaches it's start point, then perform a Reverse and HalfSpeed function at exactly the same time.

2 Writing Scripts

You may write a script using any text editor, though if you are not in the United States you need to be careful about the character encoding used for the script file. Scripts must be written in an 8-bit character encoding that is compatible with ASCII.

If the editor you use gives you an option, do not select "Unicode" or "Unicode big endian". You must use ASCII, UTF-8, ANSI, Text, or MSDOS-Text.

There have been reports of files not loading property with the ANSI or UTF-8 encoding, so if you are having problems with scripts try saving them in the simplest text encoding available.

A script file may have any name, but it is recommended that they have the extension .mos. Scripts may be stored in any directory, though many prefer to keep them in the scripts directory under the Mobius installation directory.

Once you have written a script it must be registered, which is just a way of telling Mobius where the scripts are. To register a script pull down the Configuration menu and select the Scripts... item, the Script Registration window will pop up. The large panel in the center contains the full path names of all registered script files.

To register a new script click the Add button. A file browser will pop up, navigate to the directory containing the script, highight the script file, and click Open. The file will be added to the end of the script list. To delete a registered script, click on it so that it becomes highlighted, then click the Delete button. The script will be removed from the list.

The order in which the script files appear in the Script Registration window will also be the order in which they are listed in the trigger binding windows (more on these later). If you want to change the order of the scripts, click on one so that it is highlighted, then click on the Move Up or Move Down buttons to move it to the desired location.

NOTE: The ability to order scripts will probably be taken away in future releases. Insteaed, scripts will be presented in alphabetical order.

3 Running Scripts

Scripts are run in response to a trigger, the available trigger types are MIDI events, computer keyboard keys, and buttons in the Mobius window. The association of a script to a trigger is called binding.

Once a script has been registered it will appear in the function list of all binding windows just as if it were a built-in function.

To bind a script to a MIDI event, pull down the Configuration menu and select the MIDI Control... item. The script names will appear at the top of the list of function names in the panel on the left.

To bind a script to a keyboard event, select the Keyboard Control... item from the Configuration menu. The script names will appear at the top of the list of function names in the panel on the left.

To bind a script to a button in the UI, select the Buttons... item from the Configuration menu. The script names will appear at the top of the list of function names.

See the Mobius User's Manual for more information on how to use the binding windows.

You may bind all three of the trigger types to the same script, but only one trigger of a given type may be bound to a script. In other words, a script may have a MIDI event trigger, a key trigger, and a button trigger, but it cannot have two MIDI triggers or two key triggers. This restriction will be removed in future versions of Mobius.

Some trigger types support both a down and an up trigger. When used with the !sustain declaration this allows the script to have different behavior when you press and release a footswitch or key. Triggers of this type are called momentary triggers. The momentary triggers are:

When binding a script to a MIDI event, consider whether you want to use advanced script features such as Sustain Scripts or Long Press Scripts. These features require that the script be bound to a momentary trigger.

4 Debugging Scripts

TODO: Introduce DBWIN32, Echo, Message, Prompt...

5 Script Language Basics

A script is simply a text file containing lines of characters with each line ending with a return character. Each line of text will be one of the following types:

For a given line of text the first significant character determines the type. The first significant character is anything other than white space characters such as spaces and tabs.

If all the characters on a line are white space, the line is empty and is ignored.

If the first significant character is a # the line is a comment and the entire line is ignored.

If the first significant character is a ! the line is a declaration.

If the first significant character is anything other than whitespace, # or ! the line is a statement.

Declarations are used to give Mobius information about how to run the script. They can appear anywhere in the script but it is recommended that you put them all at the top. The order of declarations is not important.

Statements are performed in the order they are written in the script.

This example script shows each of the line types.

  # Do the NextLoop function after turning off switch quantize
  !name Next Loop Now

  set switchQuant off
  NextLoop

The first line begins with a # so it is a comment. You may put comments anywhere in the script to explain what the script is doing.

The second line is a declaration, in this example it is specifying the name you want to display in the binding windows.

The third line is empty.

The fourth and fifth lines are statements.

GEEK NOTE:If you have experience with other programming languages, note that Mobius does not support multi-line statements (with or without a line continuation character) and there are no block comments. If you don't know what that means don't worry. All that you need to remember is that a comment, declaration or statement must all be one one line.

5.1 Anatomy of a Statement

A statement always begins with a Keyword which is a sequence of letters and numbers with no spaces. Example keywords are Record, set, and if. When we talk about statements, we usually identify them by their keyword, such as a Record statement or an if statement.

After the keyword, a statement may contain arguments or an expression. An argument is a single word or number without spaces, an expression is a complex sequence of characters that may include spaces. Consider this example:

  Variable nextLoop

In the previous example the keyword is Variable so this is called a Variable statement. After the keyword is the argument nextLoop. The meaning of the argument depends on the keyword, in this case the argument is the name of a script variable. Here is a more complex example:

  Variable nextLoop loopNumber + 2

In a Variable statement, all of the characters after the name argument are an expression. This expression is used to calculate the initial value of the variable. In this example loopNumber + 2 is the expression.

Some statements have no arguments, a few have more than one argument. But a statement can have at most one expression. When a statement has both an argument and an expression, the argument comes first.

5.2 Intrinsic and Function Statements

There are two categories of statements: those that are an intrinsic part of the scripting language, and those that perform Mobius looping functions. Examples of intrinsic statements are variable, set, if and for. Examples of function statements are Record, Overdub and NextLoop.

The intrinsic statements do not change often, but new function statements are added frequently. All the Mobius functions that are visible in the binding windows may be used in scripts, as well as several special functions that are available only in scripts. Whenever we talk about new functions being added to Mobius, you can assume that these functions can also be used in scripts.

GEEK NOTE:If you are familiar with the C language, you can think of intrinsic statements as being similar to the core C language, and the functions being similar to the "stdio.h" standard library.

All of the intrinsic statements will be described in detail because you need to understand all of them to write complex scripts.

The names of the function statements will be listed for reference, but we will not describe in detail what each function does. The Mobius User's Manual will have a full description of how each function behaves. Unless stated otherwise, you can assume that a function called from a script will behave the same as a function triggered with a MIDI event.

5.3 Case Insensitivity

The script language is case insensntive which means that upper case and lower case letters are considered to be the same. In the examples you will see, function names usually start with a capital letter and and variable names start with a lowercase letter. When a function or variable name contains more than one word, a capitalization style called "camel case" is used which means that the initial letter of adjacent words are upper case and the other letters are in lower case. For example:

  NextLoop
  Variable saveQuantize quantize

You do not have to follow this style, "NextLoop", "nextloop", "NEXTLOOP", or "NeXtLoOp" all mean the same thing.

The examples use inconsistent case for the intrinsic statement keywords. Keywords whose names are found in common programming languages are usually written in all lower case, these include if, else, for, and while.

Other keywords are usually capatilized, such as Variable, Label, and Jump.

NOTE: Case insensitivity is not fully support in 1.30g. These bugs have been reported.

Until these are fixed, you are advised to follow the capitalization style used in this manual.

5.4 Parameters and Variables

TODO: The difference between parameters and variables, User defined and system variables, variable scoping...

5.5 The Mysterious $

The $ is a special character used to indicate that the word that follows it is a parameter or variable reference. In early versions of Mobius the $ was required for references, now it is optional in most places. Since it appears in example scripts it tends to keep reappearing even though it is not required.

The $ is required in a few statements where it is not clear whether a word is a reference, or simply a word. These statements are:

These functions all use the remainder of the line following the keyword as a message to be displayed to the user. The message will be displayed exactly as it is written. For example the statement "Message mode" will display the string "mode". If you want to display a message with the name of the current looping mode, you reference the mode variable with a $.

  Message The current mode is $mode

6 Script Execution Environment

NOTE: This section introduces concepts that may be difficult for people without programming experience to understand. It is not necessary to understand this section in order to write scripts. But if you write scripts using the Wait statement, the !sustain declaration, or the !multiclick declaration, this section will help you understand how to get the most power out of these features.

Scripts are similar to a re-entrant function in a multi-threaded programming language. These concepts should be familar to most programmers, but they basically mean that there can be several copies of the script running at the same time.

Each of the calls for the down transition, up transition, and sustain notifications are done in an environment similar to a thread. If you use Wait statements, it is possible for the script to be active in more than one thread. By using variables, the threads can communicate with each other.

More here...

7 Script Language Reference

7.1 Declarations

In this section we will describe the declarations. These may appear anywhere in the script though there are usually written at the top.

7.1.1 !autoload

Normally scripts are loaded once when Mobius is first started and remain in memory for as long as Mobius runs. If you make changes to the script file they will not be used by Mobius until you shut it down and restart it.

The !autoload declation will cause the script file to be reloaded from the file system every time the script is called. This is very useful when writing new scripts, it allows you to keep Mobius running while you make changes the script.

After the script is working properly you should remove this declaration. Realoading the script takes time. If you are trying to call the script at precice locations in the loop, the reload will delay the running of the script slightly.

7.1.2 !controller

This option identifies the script as a controller script. When the script is triggered by a MIDI continuous controller, the script is called whenever the value of the controller changes.

Normally, when a script is bound to a MIDI continuous controller, it is assumed that the controller events are being sent by a momentary switch rather than an expression pedal. Momentary switches typically send a non-zero controller value when the switch is pressed and a zero value when the switch is released. Mobius will only call the script when it receives a non-zero value which means the switch has been pressed. It will not call the script when it receives a zero value after the switch is released, unless you also use the !sustain declaration.

This behavior is usually not desired when the continuous controller values are being generated by an expression pedal. With an expression pedal, you want the script called whenever the position of the pedal changes, even when it goes to zero.

Controller scripts are most often used to change the track controls:

  • Input Level
  • Output Level
  • Feedback
  • Secondary Feedback
  • Pan

They may also be used to change rate and pitch shift for each track, and change preset paramters such as 8ths Per Cycle.

Including the !controller declaration in a script will disable the following directives if they also appear in the script.

  • !quantize
  • !switchQuantize
  • !sustain
  • !multiclick
  • !spread

Here is an example script that implements a basic volume control. The behavior of this scipt is exactly the same as binding a controller to the Output Level control.

  !name Output Level
  !controller
  set outut midiValue

The !controller declaration tells Mobius that this script should be called every time the value of the trigger changes. The word midiValue is a reference to a system variable that will contain the value of the continuous controller that triggered this script. The value will be from 0 to 127.

Here is a more interesting example that sets the output level to the inverse of the controller value. When the controller value is zero (toe up) the output level will be 127, when the controller value is 127 (toe down) the output level will be zero.

  !name Backwards Output Level
  !controller
  set output 127 - midiValue

If you are familar with the EDP, controller scripts give you the ability to implement "flip mode" as well as many other combinations of Mobius controls that change in response to a single expression pedal.

7.1.3 !focuslock

Normally scripts do not obey focus lock or track groups. When a script is run it will only run in the selected track.

The !focuslock declaration makes the script sensitive to track focus lock and track groups. The script will be run simultaneously in all focused locked tracks, and all tracks in the same track group as the selected track.

This option is useful for simple scripts that only operate on one track. It makes the script behave more like the built-in Mobius functions. If however the script uses the for statement to operate on several tracks, you normally never use the !focuslock option.

7.1.4 !multiclick

This option allows the script to change behavior if you trigger it more than once within a short time. Some people think of this as "double clicking". A script that uses this option is called a multi-click script.

To create a multi-click script, add this declaration:

  !multiclick 2000

The numeric argument is the trigger expiration period expressed as a number of milliseconds. The default expiration period is 1000 (1 second) so you only need to include this argument if you want a value other than 1000. In this example the expiration period will be two seconds.

Next add Label statements to the script with these names:

  • click - run whenever the script is triggered again before the expiration period
  • endClick - run when the trigger expiration period is reached

As always this is best described with an example:

  !name Multiclick Test

  # the default value is 1000 milliseconds, override to 2 seconds
  !multiclick 2000

  Message Starting Click Test
  end

  Label click
  Message Click $clickCount
  end

  Label endClick
  Message Ending Click Test
  end

When you trigger the script for the first time, the message "Starting Click Test" is displayed. If you trigger the script again within 2 seconds, a message is displayed showing the number of triggers that have been received from the system variable clickCount. If you wait 2 seconds without triggering the script again, the "Ending Click Test" message is displayed and the script is finished.

Each time the script is triggered, the expiration period starts over at 2 seconds.

GEEK Note: As with sustain scripts, the click and endClick labels are called in different threads so the script may be active in more than one thread. Variables can be used for communication between threads.

7.1.5 !name

This declaration is used to specify the name to be displayed for this script in the binding windows. If no name is specified, the file name is displayed. It is very common to use a !name declaration since the script file name is not always meaningful to the user.

The name consists of all characters after the space after the !name declaration up to the end of the line. In the following example, the name displayed for the script would be "Auto Record 4".

  !name Auto Record 4

Like all declarations, !name may appear anywhere in the file but it is usually the first line to make it easier to see.

7.1.6 !quantize

Normally scripts will not obey the quantize parameter in the preset. When a script is triggered it will be run immeidately.

The !quantize option makes the script sensitive to the quantize parameter, it will be run at the next quantization point. This makes scripts behave more like built-in functions.

This option is most often used when the script does not begin with a Wait statement.

7.1.7 !spread

This option will allow the script to be triggered by a range of MIDI note, controller, or program events. The script is bound once to the center of the range, but will then be triggered by events on either side of the center.

This option is usually used when binding to MIDI note events. If the script is bound to middle C, then notes on either side of middle C will automatically be bound to the script. This is similar to the way the Pitch Shift and Rate Shift functions behave. The note you select in the Binding window is the center note, pressing notes below the center lowers the pitch/rate, pressing notes above the center raises the pitch/rate.

For spread scripts, the script will be run when any note in the range is pressed. The script can then reference internal variables to determine which note within the range was pressed.

While it will be most common to bind spread scripts to MIDI notes so that you can "play" the script chromatically, you can also bind the script to a range of program changes or continuous controller values.

To define a spread script, include this declaration at the top:

  !spread

The default range of the spread is 48 values on either side of the center, which for notes means 4 octaves up and 4 octaves down. You can reduce this range by adding an argument to the !spread declaration:

  !spread 4

In the previous example, the 4 argument means that the spread will be 4 notes on either side of the center.

If there is a conflict between a spread script binding and another function that is bound to a specific note, the other function will have priority. For example, if a spread script with a range of 12 is bound to note 64, the script will be called whenever notes 52 to 76 are received. If you also have the Record function bound to note 59, that note will call the Record function, but all the notes around it will still call the script. You can think of this like "holes being punched" into the spread range. You usually do not want to have a spread range conflict with another function binding so it is best to move the center notes so they do not overlap. If you want to have a large spread range, you will need to use different MIDI channels for the center notes.

When a spread script is called, the following system variables may be referenced to adjust the behavior of the script:

  • triggerOffset - A positive or negative integer representing the relative position of the trigger from the center of the range.

For example, if you bind the script to note 64 and you press note 63, the value of triggerOffset will be -1. If you press note 64 triggerOffset will be 0, and if you press note 65 triggerOffset will be 1.

The built-in Rate Shift function could be implemented with this script:

  !name Script Rate Shift
  !spread 12
  RateShift triggerOffset

Spread scripts are probably most useful with the RateShift, PitchShift, LoopTrigger, and TrackSelect functions. But you could also use them to set the ouput level or 8thsPerCycle parameter.

As a more interesting example, if you always want to rate shift in octave intervals, you could use this script and you would only need to reserve 9 notes:

  !name Rate Shift Octaves
  !spread 4
  RateShift triggerOffset * 12

7.1.8 !sustain

This option will cause the script to be run on both the down and up transitions of the trigger. A down transition happens when you press a switch, an up transition happens when you release a switch. A script that uses this option is called a sustain script. Sustain scripts are effective only if you are using a momentary trigger such as a MIDI note, MIDI continuous controller, or computer keyboard key.

To use MIDI notes, the trigger device must send a Note On event when a switch is pressed and a Note Off event when the switch is released. To use MIDI continuous controllers, the switch must send a CC value greater than zero when the switch is pressed and zero when the switch is released. Note that you can not use MIDI program changes for sustain scripts since the program change is only sent when the switch is pressed.

Sustain scripts are also run repeatedly while the switch is held down, this allows it to change behavior depending on how long the switch is held. This allows scripts to have long press behavior like other built-in functions.

To be notified when the trigger goes up, you simply add this label to the script:

  Label endSustain

The statements following this label will be run when the function trigger goes up.

To be notified while the trigger is held, add this label to the script:

  Label sustain

The statements following this label will be run every 250 milliseconds (1/4 second) while the trigger is held. You can determine how long the trigger has been held by testing the sustainCount variable. This will have a number starting at 1 and incrementing by 1 every time the sustain script is called.

You can specify the duration of the sustain notifications by adding a number after the !sustain keyword. This number is the number of milliseconds between notifications. For example, this declaration will cause the sustain label to called every second rather than every 1/4 second.

  !sustain 1000

Here is a more complex example that demonstrates all of the features of sustain scripts.

  !name Sustain Test

  # default is 250 msec, raise it to 1 sec
  !sustain 1000

  # the Message statement can be used to display brief messages
  Message Starting sustain test
  end

  Label sustain
  Message Sustained $sustainCount
  end

  Label endSustain
  Message Ending sustain test
  end

You can think of this as 3 scripts in one. From the top to the first end are the statements that are run when the switch is pressed.

The statements from Label sustain to the next end are called as the switch is held.

The statements from Label endSustain to the next end are called when the function trigger goes up.

You do not need to declare both labels, but you do need to remember to put an end before each of the sustain lables.

GEEK Note: Scripts are similar to a re-entrant function in a multi-threaded programming language. Each of the calls for the down transition, up transition, and sustain notifications are done in an environment similar to a thread. If you use Wait statements, it is possible for the script to be active in more than one thread. By using variables, the threads can communicate with each other.

Here is a more realistic example. A long-press of the Record function will normally perform a Reset. This script does something similar but with the Mute function.

  !name Mute/Reset

  Mute
  end

  Label sustain
  if sustainCount = 1
  Reset
  endif

Under the sustain label, you can test the sustainCount variable to make the script change behavior the longer the trigger is held. Some examples of this might be:

  • change rate or pitch shift the longer the trigger is held
  • bounce between half speed and normal speed every second as long as the trigger is held
  • slip forward one subcycle every 1/2 second

Here is another example of simle sustain sccript that raises the rate a fifth while held and drops it back when released.

  !name SUSRateUp5

  RateUp 7
  end

  Label endSustain
  RateDown 7
  end

7.1.9 !switchQuantize

When you change loops with the switchQantize parameter set something other than off, Mobius will enter a special Switch mode while it waits for the next switch quantization point. During this mode, many functions that you trigger are queued and performed after the loop switch.

By default scripts do not wait until after the loop switch, they are run immediately. The !switchQuanitze option will delay the execution of the script until after the loop switch. This makes scripts behave more like built-in functions.

Note however that the functions performed by the script are not treated like alternate endings to the switch function. For example, if you do an Overdub during the switch quantization and the next loop is empty, the current loop is copied into the next loop. But if you run a script whos first function is Overdub, this will not cause the loop to be copied.

7.2 Expressions

7.3 Intrinsic Statements

Note that some of the intrinsic statements are intended for use only in special testing scripts. The statement keywords are presented using the character case that is most often seen in the example scripts. As mentioned in the Case Insensitivity section, case in function names is ignored.

7.4 Special Labels

7.5 Functions

All Mobius functions may be used in scripts. The names of the functions used in scripts may differ slightly from the names you will see in the UI. In particular, script function names never contain spaces. If a function name is displayed in the UI with spaces such as "Next Loop", the script function name is usually the same with the spaces removed such as "NextLoop".

There are also a few functions that may be used only in scripts, they will not appear in the UI.

The function names displayed in the UI are taken from a file that may be modified by the user. This file is called a message catalog. The default message catalog is in the Mobius installation directory and is named Catalog_USEnglish.txt. If you have modified this file, or if you have asked Mobius to read messages from a different file, the names that appear in the tables below may not be the same.

The following table lists all of the Mobius functions with both the default UI name and the script name.

When the UI name is displayed as * it means that this function is only accessible from scripts.

When the script name is followed by a space, then an italic n, it means that you may type a numeric argument to the function. For example Loop1 is the same as Loop 1. This is most useful for functions such as InstantMultiply, PitchShift and RateShift where there are not unqualified function names defined for every possible argument value.

Script NameUI Name
AutoRecordAuto Record
BackwardBackward
BounceBounce
CheckpointCheckpoint
ClearClear
Divide n*
Divide2Instant Divide 2
Divide3Instant Divide 3
Divide4Instant Divide 4
DriftDrift
FocusLockFocus Lock
ForwardForward
FullSpeedFull Speed
GeneralResetGeneral Reset
GlobalResetGlobal Reset
GlobalMuteGlobal Mute
GlobalPauseGlobal Pause
HalfSpeedHalf Speed
InsertInsert
InsertOnlyInsert Only
InstantMultiply n*
InstantMultiply2Instant Multiply 2
InstantMultiply3Instant Multiply 3
InstantMultiply4Instant Multiply 4
Loop n*
Loop1Loop Trigger 1
Loop2Loop Trigger 2
Loop3Loop Trigger 3
Loop4Loop Trigger 4
Loop5Loop Trigger 5
Loop6Loop Trigger 6
Loop7Loop Trigger 7
Loop8Loop Trigger 8
MoveMove
MultiplyMultiply
MuteMute
MuteOff*
MuteOn*
MuteRealignMute Realign
MuteStartSongMute + MIDI Start Song
NextLoopNext Loop
NextTrackNext Track
OverdubOverdub
OverdubOff*
OverdubOn*
PausePause
PitchDownPitch Down
PitchNextPitch Next
PitchNormalPitch Normal
PitchPrevPitch Prev
PitchShift nPitch Shift n
PitchUpPitch Up
PlayPlay
PrevLoopPrevius Loop
PrevTrackPrev Track
QuantMidiStartPointQuant MIDI Start Point
RateDownRate Down
RateNextRate Next
RateNormalRate Normal
RatePrevRate Prev
RateShift nRate Shift n
RateUpRate Up
RealignRealign
RecordRecord
RedoRedo
RehearseRehearse
ReplaceReplace
ResetReset
ResumeScriptResume Script
RetriggerRetrigger
ReverseReverse
Sample n*
Sample1Sample Trigger1
Sample2Sample Trigger2
Sample3Sample Trigger3
Sample4Sample Trigger4
Sample5Sample Trigger5
Sample6Sample Trigger6
Sample7Sample Trigger7
Sample8Sample Trigger8
SamplePlaySample Play
SaveAudioRecordingSave Audio Recording
SaveLoopSave Loop
SaveScriptRecordingSave Script Recording
ShuffleShuffle
SlipSlip
SlipBackwardSlip Backward
SlipForwardSlip Forward
SoloSolo
SpeedSpeed
StartAudioRecordingStart Audio Recording
StartPointStart Point
StartScriptRecordingStart Script Recording
StopAudioRecordingStop Audio Recording
StopScriptRecordingStop Script Recording
StartSongMIDI Start Song
StopSongMIDI Stop Song
StutterStutter
SubstituteSubstitute
SUSInsertSustain Insert
SUSMultiplySustain Multiply
SUSMuteSustain Mute
SUSMuteRetriggerSustain Mute Retrigger
SUSNextLoopSustain Next Loop
SUSOverdubSustain Overdub
SUSPrevLoopSustain Prev Loop
SUSRecordSustain Record
SUSRehearseSustain Rehearse
SUSReplaceSustain Replace
SUSReverseSustain Reverse
SUSSpeedSustain Speed
SUSStutterSustain Stutter
SUSSubstituteSustain Substitute
SUSUnroundedMultiplySustain Unrounded Multiply
SUSUnroundedInsertSustain Unrounded Insert
SyncMasterSet Sync Master
Track n*
Track1Select Track 1
Track2Select Track 2
Track3Select Track 3
Track4Select Track 4
Track5Select Track 5
Track6Select Track 6
Track7Select Track 7
Track8Select Track 8
TrackGroupTrack Group
TrimEndTrim End
TrimStartTrim Start
UndoUndo

7.6 Modes

This table lists the possible values of the mode varaible.

7.7 Parameters

7.8 System Variables

8 Examples

8.1 Sustain Scripts

8.2 Long Press Scripts