Skip to content

Monitoring using Custom Messages

Using expressions, it is possible to customise the values sent by OSC Event Transport output messages. This page covers how to customise the output messages from the OSC Event Transport.

Adding a message

Adding output message

After the user clicks on the + button at the bottom of the Output Messages list, a new row is added. The row starts off with the entry for the OSC address selected and editable. All message rows must have a unique, non-blank OSC address to be valid.

Once the address is entered, a note in the Description column may be useful to keep track of what is being added. Alternatively, the user might want to dive straight in and press the Edit… button, to start entering the expression to create the desired value.

Invalid expressions cause the Edit… button to turn red. The error is described in mouse hover text on the button.

Variables

The OSC Event Transport has a number of local system variables which can be used to provide access to the transport which the OSC Event Transport is attached to.

Resource variables

Access to the current context of the transport is accomplished by accessing the Resources which make up the Transport. These variables can have fields referenced from them. Not all fields are documented, because this is directly accessing Designer internal objects, which are subject to change.

  • transport - The Transport Manager which the Event Transport is monitoring.
  • track - The current track within the transport.

Track time variables

Finding the current section or time within the track is simplified by providing these variables.

  • currentBeat - The current beat on the track (for use with the Quantiser.)
  • currentTime - The current time on the track.
  • currentSection - The current section number on the track (first section is numbered 0.)
  • currentSectionName - The name (note) at the start of the current section.
  • nextSectionName - The name (note) at the start of the next section.
  • currentSectionTag - The tag (e.g. TC time) at the current section.
  • nextSectionTag - The tag at the next section.

Feature variables

Features are either notes or tags. It is convenient to reference relative to a note or tag, whichever is closest. These variables deal with a complex set of lookups by storing that information in these variables.

  • currentFeatureTime - The time of the most recent feature before the current track position. Evaluates to 0.0 if no feature exists.
  • currentFeatureName - The name of the most recent feature before the current track position. Evaluates to "Start" if not feature exists.
  • nextFeatureTime - The time of the next feature after the current track position. Evaluates to track.lengthInSec if no feature exists.
  • nextFeatureName - The name of the next feature after the current track position. Evaluates to "End" if not feature exists.

See constructing feature variables for information on how these are constructed and for tips on how to get related information.

Function variable

Timecode is a special function-style variable which converts a time in seconds (e.g. currentTime) into a string in timecode format “HH:MM:SS .FF”.

Default output messages

It can be instructive to understand the meaning of the expressions which drive the default output messages.

Heartbeat

1 - (uptime % 1)

This counts down from 1 to 0 every second. uptime is a global variable

Track name

track.description

This is the description of the current track - all Resources have a description property which can be used to check which Resource an expression is accessing.

Track ID

track.trigger_note

This property is documented under Track ID. It is a discoverable via the alt-dragging technique.

Track position

Timecode(currentTime)

Converts the current time into the track into a Timecode string representation using the Timecode function. Note the result is not a Timecode object, but a string which looks like timecode. This may change in future versions of the software.

Timecode

transport.beatToTimecode(currentBeat).__str__()

The TransportManager’s beatToTimecode function matches the current track time against TC tags and provides that time as the global timecode time.

The .__str__() is an unfortunate issue with the current expression system being unable to seamlessly convert Timecode objects to string.

Current section name

track.noteAtBeat(track.sectionToBeat(currentSection))

The Track’s noteAtBeat function is used to look up notes if at an exact beat. For example, track.noteAtBeat(currentBeat) would only return a note if the play head was exactly on a note.

This expression attempts to provide more useful information by referencing back to the most recent section. Tracks’ sectionToBeat converts the current section number into its corresponding beat, to enable the lookup of any note which may be at the beat at the beginning of that section.

Next section name

track.noteAtBeat(track.sectionToBeat(currentSection + 1))

This function is very similar to the above Current section name. However, instead of looking up the current section, it instead looks up currentSection + 1, i.e. the next section.

Section hint

format::{currentFeatureName:s} +{Timecode(currentTime - currentFeatureTime):s} {nextFeatureName:s} -{Timecode(nextFeatureTime - currentTime):s}

This expression attempts to provide a readable overview of the position in the current track, relative to known feature points (either notes or tags).

Volume

transport.volume

The current volume of the Transport is discoverable via the alt-dragging technique.

Brightness

transport.brightness

The current master brightness of the Transport is discoverable via the alt-dragging technique.

BPM

track.bpmAt(currentBeat)

When working with quantised tracks, the BPM can vary between sections. The Track’s bpmAt function converts from a beat to a BPM to allow for inspection.

Play mode

transport.player.playMode.__str__()

The TransportManager has a TrackPlayer member called player. This stores a number of relevant values to the current state of the play head. The playMode member provides the current transport state as an enum value. The __str__() call converts that to a string for display to the user.

Example expressions

DescriptionExpression
Name of the tracktrack.description
Name of the transporttransport.description
Transport engaged statustransport.engaged
First beat of current sectiontrack.sectionToBeat(currentSection)
Convert current track time in beats to secondstrack.beatToTime(currentBeat)
Convert current track time in seconds to beatstrack.timeToBeat(currentTime)
Time remaining until next track featureTimecode(nextFeatureTime - currentTime)
Time elapsed since last track featureTimecode(currentTime - currentFeatureTime)
Current section time elapsedTimecode(currentBeat - track.sectionToBeat(currentSection))
Current section time remainingTimecode(track.sectionToBeat(currentSection + 1)-(currentBeat))
Current incoming timecodetransport.timecode.current.__str__()
Current Transport Manager monitoring status (e.g. timecode)transport.monitorString
Current Transport Manager status (e.g. “No matching timecode”)transport.statusString

Constructing feature variables

The variables currentFeature* and nextFeature* are constructed by the OSC event transport for the users convenience. A feature is composed from the notes and tags on the current track.

This section adds information on how they are constructed to enable access to lower level information for custom reporting. Note the functions used here are not guaranteed to remain, though they are very stable internal APIs.

First, the beat of the note or tag is found:

ActionFunctionNot found value
Next notetrack.findBeatOfNextNote(currentBeat)1.7976931348623157E+308
Previous notetrack.findBeatOfLastNote(currentBeat)-1.0
Next tagtrack.findBeatOfNextTag(currentBeat)1.7976931348623157E+308
Previous tagtrack.findBeatOfLastTag(currentBeat)-1.0

Note that the results are in beats, not in time. track.beatToTime() allows the beat to be converted to a track time, and Timecode() allows the time to be shown as timecode.

The name of a note or tag can be found with track.noteAtBeat() or track.tagAtBeat(). If an invalid beat or a beat with no note or tag is passed, the function returns an empty string.

With the above information, we can therefore emulate the construction of the various feature variables (beware these are very long, hence why the convenience variables exist.) The variables currentFeatureBeat and nextFeatureBeat do not exist normally, but are used to simplify the construction of the others for the purposes of documentation.

Feature variable
Expression
currentFeatureBeatmax(track.findBeatOfLastNote(currentBeat), track.findBeatOfLastTag(currentBeat))
nextFeatureBeatmin(track.findBeatOfNextNote(currentBeat), track.findBeatOfNextTag(currentBeat))
currentFeatureTimetrack.beatToTime(currentFeatureBeat)
nextFeatureTimetrack.beatToTime(nextFeatureBeat)
currentFeatureNameformat::{track.noteAtBeat(currentFeatureBeat)}|{track.tagAtBeat(currentFeatureBeat)}
nextFeatureNameformat::{track.noteAtBeat(nextFeatureBeat)}|{track.tagAtBeat(nextFeatureBeat)}