Show Track Expressions

Each track you add to a show can have its own set of expressions which apply to that track, allowing you to take actions when the track is loaded on a player, starts or stops playing, and so on. To react to more specific regions of the track, see the Cue Expressions, below.

The track expressions can be accessed from the track’s context menu. In addition to the globals and trigger-globals atoms and the show value described above, these have access to a very similar locals atom which can be used to share values across expressions within the track itself (but not other tracks; each gets its own locals map), a track value that contains everything Beat Link Trigger knows about the track, and individual kinds of expressions will automatically have other values available to them which make sense in the context in which the expression is used.

The help text below the expression editor will list and explain the values that are automatically available for use in that kind of expression.

Setup Expression

This is run when the Show file is opened, either because you explicitly opened it using the Triggers window File menu, or because Beat Link Trigger automatically reopened it at launch because you had it open the last time you used the program. You can use it to open network connections or set up other values for this Track and its Cue expressions to use.

Enabled Filter Expression

The basic concept of an Enabled Filter is described in the introduction to the Expressions section; tracks use them in a similar way. If the track’s Enabled menu is set to Custom, it will run its Enabled Filter Expression to decide what to do. If your expression returns a true value, this track will be enabled; otherwise it will be disabled.

Disabled Tracks do not respond to being played, and all of their configured cues are disabled.

Enhanced On-Air Example

As an example of a useful Enabled Filter Expression, one of the most convenient Enabled Filter options is On-Air, which will prevent your cues from running when a DJ is previewing a track in his headphones, but run them once it is actually playing through the house speakers. But this runs into trouble if the DJ also likes to fade out tracks to coax the audience to sing along: your On-Air filter will stop your cues while the track is faded out completely.

To fix this, we can write an Enabled Filter expression that enables the track both when it is On-Air, and when it temporarily goes off the air, as long as it is still playing, and was previously enabled. Here’s the custom Enabled Filter expression code that implements this goal:

(let [signature   (get-in show [:loaded device-number])
      any-on-air? ((set (vals (:on-air show))) signature)
      new-state   (swap! globals update :enable-locked
                         (fn [old-locks]
                           (let [locked (get old-locks device-number)]
                             (if (and playing?
                                      (or on-air? (= locked signature)))
                               (assoc old-locks device-number signature)
                               (dissoc old-locks device-number)))))]
  (or (get-in new-state [:enable-locked device-number])
      any-on-air?))
You can also set the Enabled menu to Default in order to run the Show-level Default Enabled Filter as described above. This expression probably deserves to live at the Show level, and then you can tweak individual tracks that should behave differently. The expression explanation found there also walks through an earlier, simpler version of the expression, and explains why it was not quite enough.

Loaded Expression

This is called when the track is first loaded into any player. (The same track might be loaded into multiple players at the same time; this expression is called only when the first player loads it. The track will continue to be considered loaded until the final player unloads it.)

If you want this expression to run, make sure the track’s Loaded Message menu is set to Custom.

This expression is only called when the track is enabled (disabled tracks are not considered loaded).

Playing Expression

This is called when some player begins to play the track. (The same track might be playing on multiple players at the same time; this expression is called only when the first player starts playing it. The track will continue to be considered playing until the final player stops playing it.)

If you want this expression to run, make sure the track’s Playing Message menu is set to Custom.

This expression is only called when the track is enabled (disabled tracks are not considered to be playing).

As an example, here is a Playing Expression that would do the exact same thing as setting the track’s Playing Message menu to Note:

(when midi-output
  (midi/midi-note-on midi-output playing-note 127 (dec playing-channel)))

The (when midi-output …) clause that wraps the midi-note-on call just protects against the situation where the chosen output can’t be found because it isn’t plugged in at the moment. Without this, the attempt to send the note will throw an exception that gets written at length to the log file. In the context of this Expression, the midi-output variable is set to the MIDI output device chosen for the Track, and will be nil if that device is not currently connected.

This uses the embedded MIDI library to send a Note On message to the Track’s chosen output device. The variable playing-note is set to the note number chosen for the Track’s Playing Message, 127 is the maximum MIDI note velocity, and playing-channel is set to the channel chosen for the Track, but since the user interface displays MIDI channel numbers in the traditional user-centric range from 1 to 16, and the actual protocol requires them to be sent in the 4-bit range 0-15, we need to subtract 1 from the variable value before sending it, which is what the dec (decrement) function does.

You can tweak this to send different notes (by substituting your own value or variable for playing-note) at different velocities (by replacing the 127) on different channels, or of course do something else completely. The Track Stopped discussion below shows what you would need to set up to emulate the other half of the Note mode using your own expressions.

Beat Expression

Called whenever a beat packet is received from a player that is playing this track, as long as the track is enabled.

Tracked Update Expression

Called whenever a status update packet is received from a player that has this track loaded, after the Enabled Filter Expression, if any, has had a chance to decide if the track is enabled, and after the Loaded, Playing, Stopped, or Unloaded expression, if appropriate.

If the track is not enabled, this expression is not called.

Stopped Expression

This is called when the last player that had been playing the track stops. (The same track might be playing on multiple players at the same time; this expression is called only when the final player stops playing it, so it is no longer playing on any player.)

If you want this expression to run, make sure the track’s Playing Message menu is set to Custom.

A track will also report stopping if it becomes disabled while it was playing.

To complete the example introduced in the Playing Expression above, here is an expression that sends the same MIDI event when a track stops that you get by setting the Playing Message menu to Note:

(when midi-output
  (midi/midi-note-off midi-output playing-note (dec playing-channel)))

As described in the initial example above, this checks to be sure the MIDI output device that has been selected for the track is currently connected before sending it a Note Off message for the configured note and channel. Again, you can tweak this to send different messages. For example, you might actually want to send a different Note On message when the track stops playing; for that, you would use the same code shown in the Playing Expression section.

Unloaded Expression

This is called when the track is unloaded from the last player that had loaded it. (The same track might be loaded into multiple players at the same time; this expression is called only when the final player unloads it, so it is no longer loaded in any player.)

If you want this expression to run, make sure the track’s Loaded Message menu is set to Custom.

A track will also report unloading if it becomes disabled while it was loaded.

Shutdown Expression

This is run when the Show file is closed, either because you closed the window, or because Beat Link Trigger is shutting down. You can use it to close any network connections or clean up any other resources your Setup Expression allocated.