Pangolin BEYOND Advanced
Pangolin BEYOND is such flexible and powerful laser show software that Deep Symmetry invested in a Windows virtual machine purely to be able to use it to control our best laser projector. With an Advanced license, you can send it PangoScript commands over the network to achieve a deep level of integration with other systems. Here are some ways you can use it with Beat Link Trigger.
|This section shows how to achieve tight integration using the PangoTalk UDP server, which requires BEYOND Advanced, but you can use MIDI with BEYOND Essentials to get decent tempo tracking and basic cue triggers, as described its own section.|
To begin with, in the Shared Functions, we tell Beat Link Trigger how to communicate with BEYOND, by specifying the broadcast address of the network interface it is listening on, and the port on which the BEYOND Talk UDP server is listening. To determine these things, you can choosewithin BEYOND to bring up a window like this:
By looking at the Adapter IP and Mask lines, we can determine that the
broadcast address we want to use to reach the BEYOND Talk server is
|In versions of BEYOND prior to 2.1, it was possible to send UDP unicast messages directly to the Adapter IP address. however, starting with version 2.1, you must actually send UDP broadcast packets to the broadcast address of the subnet the server is attached to.|
Then, make sure the BEYOND UDP Talk server is enabled ():
Choose a port that is not in use by anything else on your system (the
16062 is likely fine), check the Enable Talk Server check
box, and click OK. Make a note of the broadcast address and UDP
port it is listening on, and then make sure the talk server is fully
enabled by choosing :
In older versions of BEYOND, we sometimes had to quit and restart
the program after making these configuration changes in order for them
to take effect. That is probably no longer true, but we mention this
as a potential trouleshooting step. You can also test connectivity
using a tool like Packet Sender to send
Once you have the UDP Talk server up and working, edit Beat Link
Trigger’s Shared Functions to use the broadcast address and
port to define a new function,
beyond-command, that your other
expressions will be able to use to send PangoScript commands to it:
(let [beyond-address (InetSocketAddress. (InetAddress/getByName "172.16.1.255") 16062) send-socket (DatagramSocket.)] (defn beyond-command "Sends a PangoScript command to the configured BEYOND Talk server." [command] (let [payload (str command \return \newline) packet (DatagramPacket. (.getBytes payload) (.length payload) beyond-address)] (.send send-socket packet))))
|Of course, replace the address and port in the first line with the correct values to use for your BEYOND UDP Talk server.|
With that in place, we are ready to integrate laser shows. First, let’s see how to have the tempo within BEYOND always precisely match the tempo of your master player.
Create a new Trigger in Beat Link Trigger () and label it something like “Beyond BPM Sync” in the Comment field. Configure it to Watch the Master Player, and give it a Custom Enabled Filter:
The Enabled Filter editor will pop open, so you can paste in the following code:
(swap! locals update-in [:beyond-bpm] (fn [old-bpm] (when (not= effective-tempo old-bpm) (beyond-command (str "SetBpm " effective-tempo))) effective-tempo)) nil ;; Never need to actually activate.
What this function will do is look at every status update packet that
is received from the Master Player, and see if the BPM being reported
is different from what we last told BEYOND to use (it tracks this in a
value stored in the trigger
locals map under the key
and the first time the expression is called, nothing will be found
there, so it will always start by sending the current BPM value to
When the current tempo is different from what we have sent to BEYOND,
we use the
beyond-command function that we defined in the Shared
Functions to send a
SetBpm command to BEYOND, containing the current
tempo at which the Master Player is playing. If there is no
difference, we send nothing, because BEYOND is already at the right
tempo. Either way, we record the current effective tempo in the
locals map for use when the next update packet is received.
Finally, the expression always returns
nil, because there is never
any reason for it to be enabled. It is not actually triggering
anything in response to a particular track playing, it is simply
always keeping BEYOND’s tempo tied to the master player. (For the same
reason, it doesn’t matter what you choose in the MIDI Output, Message,
and Channel menus; they will never be sent.)
Once you have this expression saved, try playing a track on the Master Player, adjust the pitch fader, and watch BEYOND smoothly and precisely track the BPM of the music being played.
With this framework in place, it is very easy to have a laser cue controlled by a trigger. Create another new Trigger, label it to describe the cue you want it to control, and set it up to be activated when an interesting track reaches an interesting beat, using the techniques described above. The only thing you need to do different is set the Message menu to Custom, so it will send its Activation message to Beyond’s Talk server rather than a MIDI message.
Actually, you can map MIDI and OSC messages to BEYOND cues, so once you have the BPM sync working, feel free to go that route if you prefer. But since we already have a Talk server running, here is how to use it.
The easiest way to identify the proper PangoScript message to use to refer to a particular cue is to take advantage of a special mode of the BEYOND laser preview window that shows you all the internal PangoScript messages it is sending itself when you interact with its user interface. Chooseand click the Laser Preview tab. Check the Display Internal BEYOND Command check box, and click OK:
One that is done, as you interact with the interface, you will see small messages at the bottom left of the laser preview section showing you the equivalent PangoScript command for what you just did:
In this case, I just activated cue 16, 20 (cue 20 on page 16). So in the trigger’s Activation Expression editor, I would use the following:
(beyond-command "StartCue 16,20")
And finally, adding the corresponding Deactivation Expression rounds out the trigger:
(beyond-command "StopCue 16,20")
With that in place, whenever this trigger activates, the specified BEYOND laser cue will start, and whenever the trigger deactivates, so will the laser cue. And when combined with the tempo synchronization set up in the previous section, the cue will look great with the music.