afterglow.show
Encapsulates a synchronized light show, executing a varying collection of effects with output to a number of DMX universes. Assumes control of the assigned universes, so only one show at a time should be assigned a given universe. Of course, you can stack as many effects as you’d like in that show.
The effects are maintained in a priority queue, with higher-priority effects running after lower-priority ones, so they can adjust or simply replace the channel assignments established by earlier effects. Some may choose to implement traditional channel-oriented highest-takes-prority or latest-takes-priority semantics, others do more sophisticated color blending or position averageing. The default priority when adding an effect is zero, but you can assign it any integer, and it will be inserted into the queue after any existing effects with the same priority.
All effects are assigned a keyword when they are added, and adding a new effect with the same key as an existing effect will replace the former one.
active-effect-keys
(active-effect-keys show)
Returns a set of the keywords assigned to all currently-active effects.
add-effect!
(add-effect! key effect & {:keys [priority from-cue x y var-map], :or {priority 0}})
Add an effect to the active set which are affecting DMX outputs for show-context/*show*. If no priority is specified, zero is used. This effect is added after all existing effects with equal or lower priority, and replaces any existing effect with the same key. Since the effects are executed in order, ones which come later will win when setting DMX values for the same channel if that channel uses latest-takes-priority mode; for channels using highest-takes priority, the order does not matter. Effects can also use more sophisticated strategies for adjusting the results of earlier effects, but the later one always gets to decide what to do.
Returns the unique id assigned to this particular effect activation, so that user interfaces can detect whether it is still active.
The :from-cue
keyword argument is used, along with :x
and :y
, to keep track of effects which were launched from the cue grid, to help provide feedback on control surfaces and in the web interface. :var-map
is used to supply a map of variable bindings associated with the cue, also for use by interfaces which support them.
add-effect-from-cue-grid!
(add-effect-from-cue-grid! x y & {:keys [velocity var-overrides], :or {velocity 127}})
Finds the cue, if any, at the specified grid coordinates, and activates its effect with the designated key and priority, after ending any effects whose keys are specified in the cue’s :end-keys
. Returns the id of the new effect, or nil if no cue was found.
Any cue variables which are configured to be responsive to MIDI velocity will be set according to the velocity value passed in with :velocity
. If no velocity is specified, then a default velocity of 127
is assumed.
A map of variable keywords to values can be supplied with :var-overrides
, and the corresponding value will be used rather than the :start
value specified in the cue for that variable when it is introduced as a cue variable. This is used by compound cues to launch their nested cues with customized values, and by afterglow-max to start cues with alternate values if its patchers have been configured to do so. If a :var-override
is specified for a variable which is also configured as velocity sensitive, the override will win.
add-empty-buffer-fn!
(add-empty-buffer-fn! f)
Arranges for the supplied function to be called when the Afterglow rendering loop is clearing its DMX buffers in order to calculate a frame of lighting effects. The function must take no arguments.
This is how custom assigner types which do not result in DMX data, such as the Pangolin beyond-server laser show integration, register their extension functions to participate in the rendering loop.
add-frame-fn!
(add-frame-fn! f)
Arranges for the supplied function to be called when the Afterglow rendering loop is going to sleep prior to rendering the next frame of lighting effects. The function will be given the metronome snapshot that will be in effect when the next frame gets rendered, so that it can preconfigure anything needed for the rendering process. This is used, for example, to allow afterglow-max patchers to set show variables for the next frame, since they cannot be queried directly during the rendering process.
add-midi-control-metronome-align-bar-mapping
(add-midi-control-metronome-align-bar-mapping device-filter channel control-number & {:keys [metronome], :or {metronome (:metronome *show*)}})
Adjust a metronome so the closest beat is considered the first in the current measure, without moving the beat, when a control-change message with non-zero value is received from the specified device, channel
, and control-number
.
The first MIDI input source whose device matches the device-filter
(using filter-devices) will be chosen.
If keyword parameter :metronome
is supplied, its value can either be a rhythm/metronome object, or a keyword naming a show variable containing such an object. If not supplied, the main metronome attached to *show* is unmapped.
Returns a MIDI mapping function which can be passed to remove-control-mapping if you later want to stop the metronome from being affected by these MIDI messages.
add-midi-control-metronome-align-phrase-mapping
(add-midi-control-metronome-align-phrase-mapping device-filter channel control-number & {:keys [metronome], :or {metronome (:metronome *show*)}})
Adjust a metronome so the closest beat is considered the first in the current phrase, without moving the beat, when a control-change message with non-zero value is received from the specified device, channel
, and control-number
.
The first MIDI input source whose device matches the device-filter
(using filter-devices) will be chosen.
If keyword parameter :metronome
is supplied, its value can either be a rhythm/metronome object, or a keyword naming a show variable containing such an object. If not supplied, the main metronome attached to *show* is mapped.
Returns a MIDI mapping function which can be passed to remove-control-mapping if you later want to stop the metronome from being affected by these MIDI messages.
add-midi-control-metronome-reset-mapping
(add-midi-control-metronome-reset-mapping device-filter channel control-number & {:keys [metronome], :or {metronome (:metronome *show*)}})
Cause a metronome to be reset to beat 1, bar 1, phrase 1 when a control-change message with non-zero value is received from the specified device
, channel
, and control-number
.
The first MIDI input source whose device matches the device-filter
(using filter-devices) will be chosen.
If keyword parameter :metronome
is supplied, its value can either be a rhythm/metronome object, or a keyword naming a show variable containing such an object. If not supplied, the main metronome attached to *show* is mapped.
Returns a MIDI mapping function which can be passed to remove-control-mapping if you later want to stop the metronome from being affected by these MIDI messages.
add-midi-control-to-master-mapping
(add-midi-control-to-master-mapping device-filter channel control-number & {:keys [master min max], :or {master (:grand-master *show*), min 0, max 100}})
Cause the specified dimmer/master in *show* to be updated by any MIDI controller-change messages from the specified device sent on the specified channel
and control-number
.
The first MIDI input source whose device matches the device-filter
(using filter-devices) will be chosen.
If :min
and/or :max
are specified, they will be used instead of the normal master range of 0 to 100. If given, both :min
and :max
must be valid percentages (in the range 0 to 100). If no :master
is supplied, the show’s grand master is mapped. If the value supplied with :master
is a keyword, it is resolved as a show variable containing a dimmer master.
Returns a MIDI mapping function which can be passed to remove-control-mapping if you later want to stop the dimmer master from being affected by these MIDI messages.
add-midi-control-to-var-mapping
(add-midi-control-to-var-mapping device-filter channel control-number variable & {:keys [min max transform-fn], :or {min 0, max 127}})
Cause the specified variable
in *show* to be updated by any MIDI controller-change messages from the specified device sent on the specified channel
and control-number
.
The first MIDI input source whose device matches the device-filter
(using filter-devices) will be chosen.
If :min
and/or :max
are specified, the normal MIDI range from 0 to 127 will be scaled to the supplied range instead.
If :transform-fn
is specified, it will be called with the MIDI value (after scaling, if any was specified), and its return value will be stored in the variable.
Returns a MIDI mapping function which can be passed to remove-control-mapping if you later want to stop the variable from responding to these MIDI messages.
add-send-buffer-fn!
(add-send-buffer-fn! f)
Arranges for the supplied function to be called when the Afterglow rendering loop is sending the DMX data for a frame of lighting effects. The function must take no arguments.
This is how custom assigner types which do not result in DMX data, such as the Pangolin beyond-server laser show integration, register their extension functions to participate in the rendering loop.
add-variable-set-fn!
(add-variable-set-fn! key f)
Arranges for the supplied function to be called when the the show variable with the specified keyword is set. The function will be called with two arguments: the keyword, and the new value which is being set.
address-map
(address-map)
Returns a sorted map whose keys are the IDs of the universes managed by *show*, and whose values are address maps for the corresponding universe. The address maps have keys for every channel in use by the show in that universe, and the value is the key of the fixture using that address.
blackout-show
(blackout-show)
Sends zero to every channel of every universe associated with *show*. Will quickly be overwritten if the show is running and there are any active effects, so this is mostly useful when a show has been suspended and you want to darken the lights it left on.
blackout-universe
(blackout-universe universe)
Sends zero to every channel of the specified universe. Will be quickly overwritten if there are any active shows transmitting to that universe.
clear-cue!
(clear-cue! x y)
Removes any cue which existed at the specified coordinates in the default show’s cue grid, by delegating to afterglow.controllers/clear-cue! (see that function for details).
clear-effects!
(clear-effects!)
Remove all effects currently active in *show*, leading to a blackout state in all controlled universes (if the show is running) until new effects are added.
clear-empty-buffer-fn!
(clear-empty-buffer-fn! f)
Ceases calling the supplied function during the buffer clearing phase of the rendering loop.
clear-frame-fn!
(clear-frame-fn! f)
Ceases calling the supplied function from the rendering loop.
clear-send-buffer-fn!
(clear-send-buffer-fn! f)
Ceases calling the supplied function during the data sending phase of the rendering loop.
clear-variable-set-fn!
(clear-variable-set-fn! key f)
Ceases calling the supplied function when the show variable with the specified keyword is set.
current-load
(current-load)
Returns a sense of how much headroom there is running the current effects, in the form of the fraction of the available refresh interval that was used calculating and sending the last several frames.
default-refresh-interval
How often should frames of DMX data be sent out; this should be a supported frame rate for your interface. The default here is 40 Hz, forty frames per second.
end-effect!
(end-effect! key & {:keys [force when-id]})
Shut down an effect that is running in *show*. Unless a true
value is passed for :force
, this is done by asking the effect to end (and waiting until it reports completion); forcibly stopping it simply immediately removes it from the show. If an id is specified with :when-id
, the effect will only be ended if the id of the currently-running effect matches the one supplied. If it was created from a cue grid, notify any controllers that might be tracking the cue state.
find-cue-grid-active-effect
(find-cue-grid-active-effect show x y)
Find the cue at a particular cue grid location. If it is marked as active, check whether there is still an effect running under that key with the same id. If so, return a vector containing both the cue and the effect. If not, mark the cue as inactive, and return a vector containing the cue and nil. If no cue was found at all, simply returns nil.
find-effect
(find-effect key)
Looks up the specified effect keyword in the list of active effects for *show*. Returns a map of the effect metadata, with the effect itself under the key :effect
. If the effect is in the process of ending, the keyword :ending
will have a true
value.
fixtures-named
(fixtures-named n)
Returns all fixtures patched into *show* whose key matches the specified name, with an optional number following it, as would be assigned to a fixture group by patch-fixture-group!
get-cue-effect
(get-cue-effect effect-fn var-map)
Sets up a cue as though it is about to run, in order to test that its effect function returns an effect. Used in validating the cue when it is created.
ola-failure-description
(ola-failure-description)
If the last attempt to communicate with the OLA daemon failed, returns a description of the problem, otherwise returns nil.
patch-fixture!
(patch-fixture! key fixture universe start-address & {:keys [x y z x-rotation y-rotation z-rotation relative-rotations rotation-matrix], :or {x 0.0, y 0.0, z 0.0, x-rotation 0.0, y-rotation 0.0, z-rotation 0.0}})
Patch a fixture to a universe in *show* at a starting DMX channel address, at a particular point in space, with a particular orientation.
key
is a keyword identifying the fixture. If you need to remove the fixture later, or re-patch it with different parameters, you can do that by passing the same keyword to remove-fixture! or patch-fixture!
. If you have a set of fixtures that you want to be able to easily group, give them keywords that start with the same name, followed by a hyphen and uniqe numbers. That way, if you pass the name portion (everthing before the final hyphen and number) to fixtures-named, you will get back a list of all those fixtures.
fixture
is a Fixture Definition map which specifies all the capabilities of the fixture and how Afterglow can control it.
universe
identifies which DMX universe the fixture is attached to, and must be one of the universe numbers that was passed in the universes
argument to show when creating the show. start-address
identifies the DMX address of the first channel the fixture is listening to in that universe (it will be displayed on the fixture’s configuration panel or DIP switches), and is an integer ranging from 1
to 512
, the legal DMX addresses in a universe. The attempt to patch will fail if there are more channels in the fixture definition than fit within the 512-channel address space starting at that address, or if any of the addresses used by the fixture have already been assigned to other patched fixtures.
Coordinates and rotations are optional, expressed along with the keyword arguments :x
, :y
, :z
, :x-rotation
, :y-rotation
, and :z-rotation
, which all default to zero if not specified. All coordinates and rotations are interpreted with respect to the show frame of reference, and are in meters and radians. You can use transform/inches, transform/feet and transform/degrees to convert those units for you if desired.
When you specify a fixture rotation using the :x-rotation
, :y-rotation
, and :z-rotation
arguments, this represents a set of Euler angles within the fixed frame of reference of show space, as implemented by transform-fixture-euler, which uses the setEuler
method of the Java3D Transform3D object. It can sometimes be very challenging, when looking at a fixture, to figure out how to calculate the Euler angles representing how it was hung. In those situations, you can use an alternate method to specify its rotations:
If you pass in the optional keyword argument :relative-rotations
, you can follow it with a vector of paired rotation keywords and angles of any length, and Afterglow will interpret them using transform-fixture-relative. Starting with the fixture at its default orientation, Afterglow will perform all the rotations you list, in order, from the perspective of the transfomed fixture at each step. This can be a lot easier to think about. For example, if the fixture was first rotated 90 degrees counterclockwise on its y axis, then 45 degrees clockwise on its (new) z axis, you would specify:
:relative-rotations [[:y-rotation (tf/degrees 90)] [:z-rotation (tf/degrees -45)]]
Finally, if you happen to have a Transform3D
object which specifies the rotation applied to the fixture (perhaps from some other program), you can simply pass that using the optional keyword argument :rotation-matrix
.
patch-fixture-group!
deprecated in 0.1.2
(patch-fixture-group! key fixture universe start-address count)
(patch-fixture-group! key fixture universe start-address count offset)
Deprecated until it supports positioning each fixture.
Patch a fixture group to a universe in *show* at a starting DMX channel address. Names will be assigned by adding a hyphen and numeric suffix, starting with 1, to the key supplied. If an offset is supplied, it will be added to the starting address for each subsequent fixture; if not, the largest offset used by the fixture will be used to calculate a suitable offset.
profile-show
(profile-show & {:keys [iterations serial?], :or {iterations 100, serial? true}})
Gather statistics about the performance of generating and sending a frame of DMX data to the universes *show*. The show must be stopped to run this function since it manipulates the thread pool atom to run the kind of test requested.
Specify the number of iterations of the rendering loop that should be profiled with the optional keyword argument :iterations
(which defaults to 100). Assumes you want to profile without the use of a thread pool to look for worst-case performance unless you pass false
with the optional keyword argument :serial?
.
register-grid-controller
(register-grid-controller controller)
Add a cue grid controller to the list available for linking in the web interface. The argument must implement the IGridController protocol.
register-show
(register-show show description)
Add a show to the list of available shows in the web interface.
remove-midi-control-metronome-mapping
deprecated in 0.2.0
(remove-midi-control-metronome-mapping device-filter channel control-number f & {:keys [metronome], :or {metronome (:metronome *show*)}})
Deprecated: There is no reason to use this function, it is simpler to call remove-control-mapping directly.
Stop affecting a metronome when the specified MIDI controller-change messages are received. This undoes the effect of any of add-midi-control-metronome-reset-mapping, add-midi-control-metronome-align-bar-mapping, and add-midi-control-metronome-align-phrase-mapping.
If keyword parameter :metronome
is supplied, its value can either be a rhythm/metronome object, or a keyword naming a show variable containing such an object. If not supplied, the main metronome attached to *show* is mapped.
f
is the function that was returned by add-midi-control-metronome-reset-mapping, add-midi-control-metronome-align-bar-mapping, or add-midi-control-metronome-align-phrase-mapping when this relationship was established.
remove-midi-control-to-master-mapping
deprecated in 0.2.0
(remove-midi-control-to-master-mapping device-filter channel control-number f & {:keys [master], :or {master (:grand-master *show*)}})
Deprecated: There is no reason to use this function, it is simpler to call remove-control-mapping directly.
Cease updating the specified dimmer/master when the specified MIDI controller-change messages are received. f
is the function that was returned by add-midi-control-to-master-mapping when this relationship was established.
remove-midi-control-to-var-mapping
deprecated in 0.2.0
(remove-midi-control-to-var-mapping device-filter channel control-number variable f)
Deprecated: There is no reason to use this function, it is simpler to call remove-control-mapping directly.
Cease updating the specified variable in *show* when the specified MIDI controller-change messages are received. f
is the function that was returned by add-midi-control-to-var-mapping when this relationship was created.
resolution-order
The order in which assigners should be evaluated, by type key. Multi-channel assignments are resolved before individual ones.
running?
(running?)
Returns an indication of whether the show is currently generating and sending values to its associated lighting universes.
set-cue!
(set-cue! x y cue)
Puts the supplied cue at the specified coordinates in the default show’s cue grid, by delegating to afterglow.controllers/set-cue! (see that function for details).
set-extension-resolution-order!
(set-extension-resolution-order! extension-key order)
A system wanting to extend the Afterglow rendering loop to support new kinds of assigners must call this function to register its new unique assigner types, and the order in which they should be run.
The first argument extension-key
is a unique keyword identifying the extension, for example a keyword created from its namespace name. The second argument is a vector containing all the keywords which identify the new assigner types which are implemented by the extension. These must also be globally unique, and should probably have a prefix related to the exension name.
Even if the extension adds only a single new assigner type, that must be passed as a single-element vector in order
so that Afterglow knows to look for and run its assigners.
show
(show & {:keys [universes base-metronome refresh-interval description grid-controller-listener], :or {universes [1], base-metronome (rhythm/metronome 120), refresh-interval default-refresh-interval}})
Create a show coordinator to calculate and send DMX values to the specified universe(s), with a rhythm/metronome to coordinate timing. The metronome to use can be specified with the optional keyword argument :base-metronome
; otherwise, a new metronome is created for the show, with a starting bpm
of 120.
Values are computed and sent at a fixed refresh interval (in milliseconds), which defaults to a frame rate of thirty times per second, but can be specified using the optional keyword argument :refresh-interval
.
If a description is supplied with the :description
argument, the show will be registered under that description for the user to choose in the embedded web interface. If you recreate the show because you are in the process of working out its details, be sure to unregister the old version (with unregister-show) first, or you will end up with multiple shows with the same description in the web interface. There is an example of how to handle this automatically at the start of afterglow.examples/use-sample-show (click the view source
link below the description to see the sample-show
atom and swap!
invocation within set-default-show!
it uses to make sure there is only ever one version registered).
If grid-controller-listener
is supplied, it will be called whenever a grid controller is registered to the show with the arguments :register
and the IGridController
implementation, and whenever one is unregistered with the arguments :unregister
and the implementation.
start!
(start!)
Starts (or restarts) a scheduled task to calculate and send DMX values to the universes controlled by *show* at the appropriate refresh rate.
stop!
(stop!)
Shuts down and removes the scheduled task which is sending DMX values for *show*, and cleans up the show’s thread pool.
stop-all!
(stop-all!)
Stops all running shows. Afterglow registers a shutdown hook to call this when the Java environment is shutting down, to clean up gracefully.
sync-status
(sync-status)
Checks what kind of synchronization is in effect for *show*, and reports on how it seems to be working.
sync-to-external-clock
(sync-to-external-clock)
(sync-to-external-clock sync-fn)
Stops or sarts synchronizing the show metronome attached to *show* with an external clock source. Pass it a function which takes the metronome and binds it to the source, returning a ClockSync object which will be stored with the show, so synchronization can later be stopped if desired. Calling this stops any synchronization that was formerly in effect, and calling it with no sync-fn argument simply leaves it stopped.
Functions useful to pass to this include midi/sync-to-midi-clock and dj-link/sync-to-dj-link.
unregister-grid-controller
(unregister-grid-controller controller)
Remove a cue grid controller from the list available for linking in the web interface.
unregister-show
(unregister-show show)
Remove a show from the list of available shows in the web interface.