From b102d2403623d515b02eac957690df6a9cbb1e0f Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 16 Jul 2022 09:16:23 +0200 Subject: Update docs --- README.md | 11 ++- docs/basic-control.rst | 136 ++++++++++++++++++++++++++++++ docs/cue-list.rst | 205 ++++++++++++++++++++++++++++++++++++++++++++++ docs/new-fixture.rst | 2 +- docs/patching.rst | 83 +++++++++---------- docs/physical-control.rst | 4 + 6 files changed, 389 insertions(+), 52 deletions(-) create mode 100644 docs/basic-control.rst create mode 100644 docs/cue-list.rst create mode 100644 docs/physical-control.rst diff --git a/README.md b/README.md index 20c8e00..8761b35 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Lighting fixtures are referred to by names, rather than numbers: ;; Turn on both moving lights and set colour (at moverL moverR 60) -(at moverL moverR 'colour (make-colour-rgb 45 10 0)) +(at moverL moverR 'colour (rgb 45 10 0)) ``` The fixture names are normal Scheme variables. You can do usual things such @@ -98,7 +98,7 @@ of cues: ;; Act 1, Scene 1 (lighting-state (at front-wash 80) - (at moverL 'colour (make-colour-cmy 2700/127 0 0))) + (at moverL 'colour (cmy 25 0 0))) (at moverL 25) (crossfade 3)) @@ -130,12 +130,11 @@ Documentation index ------------------- * [Patching fixtures](docs/patching.rst) +* [Basic attribute control and building states](docs/basic-control.rst) +* [Cue lists and playbacks](docs/cue-list.rst) * [The fixture display tool](docs/fixture-display.rst) +* [Physical controls](docs/physical-control.rst) * [Defining a new type of fixture](docs/new-fixture.rst) -* More to come: - - Basic control of attributes, building states - - Cue lists - - Using physical controls via MIDI (Non-)warranty diff --git a/docs/basic-control.rst b/docs/basic-control.rst new file mode 100644 index 0000000..f326a5d --- /dev/null +++ b/docs/basic-control.rst @@ -0,0 +1,136 @@ +=========================================== +Basic attribute control and building states +=========================================== + +Once your fixtures are patched (see ``_), you can set attributes +sing ``at``. For example, to set the intensity of ``my-dimmer`` to 100%:: + + (at my-dimmer 'intensity 100) + +If you leave out the attribute name, then ``intensity`` will be assumed:: + + (at my-dimmer 100) + +The available parameters are determined by the fixture definition (see +``_), and are referred to by their symbolic name (i.e. quote +them with ``'``). For example:: + + (at my-moving-light 'pan 32) + (at my-moving-light 'tilt 70) + (at my-moving-light 'zoom 60) + +Not all fixtures accept a single number. For example, ``'colour`` (note: UK +spelling) takes a colour object, which can be constructed using ``rgb`` or +``cmy``. Starlet (or rather, the fixture definition code) is responsible for +converting the colour to the native representation used by the fixture:: + + (at my-moving-light 'colour (rgb 80 23 25)) + +You can set attributes for multiple fixtures at once:: + + (at spotCS spotSR spotSL 90) + +Or you can set attributes for a list of fixtures:: + + (define all-spots (list spotSL spotCS spotSR)) + (at all-spots 90) + +You can mix individual fixtures and lists of fixtures. However, you can only +set one attribute (to one value) at a time. + + +The selection +============= + +When setting many attributes for one fixture, you can avoid typing the +fixture name each time by using the selection. To select a fixture, call +``sel`` with the fixture(s) to select:: + + (sel my-dimmer) + (sel all-spots my-moving-light) + +If the fixture name is left out from subsequent calls to ``at``, they will +apply to the currently selected fixture(s). To clear the selection, simply +call ``(sel #f)`` or simply ``(sel)``:: + + (sel my-moving-light) + (at 100) + (at 'colour (rgb 80 23 25)) + (at 'tilt 70) + (at 'pan 32) + (sel #f) + +The fixture display window (see ``_) will highlight the +selection, and physical control devices (see ``_) will +affect the selected fixture(s). + +To see the contents of the selection, use ``(get-selection)``. + + +State objects +============= + +Attribute values must be stored within a state object. When you set an +attribute from the Guile REPL, the values will be stored in the programmer +state. You can examine the contents using ``state-source``, which returns +the Scheme code corresponding to the state's contents:: + + (state-source programmer-state) + +You can also use ``print-state``, which just pretty-prints the output of +``state-source``. To reduce typing, you can use ``ps`` as a synonym for +``programmer-state``:: + + (print-state ps) + +You can construct new states by wrapping your ``at`` forms inside +``lighting-state``. These state objects can be used inside cue lists +(see ``_), bound to variables etc:: + + (define my-state + (lighting-state + (at spotSR spotSL 50) + (at spotCS 100))) + +The programmer state has priority over everything else (e.g. cue list +playbacks). To avoid surprises, you should make sure that it's empty before +trying to run a show. The ``clear-state!`` procedure empties a state object +of its contents, without deleting the state itself:: + + (clear-state! ps) + +There are some utility routines for handling states: + +* ``(state-empty? my-state)`` returns ``#t`` if ``my-state`` is empty, + otherwise ``#f``. +* ``(remove-fixture-from-state! my-state spotCS)`` removes all attributes for + ``spotCS`` from ``my-state``. +* ``(remove-fixtures-from-state! my-state (list spotCS spotSL))`` is the same, + but removes a list of fixtures from the state. +* ``(remove-selection-from-programmer!)`` removes from the programmer any + attributes referring to fixtures which are currently selected. It is + defined as follows:: + + (define (remove-selection-from-programmer!) + (remove-fixtures-from-state! + programmer-state + (get-selection))) + + +Effects +======= + +Attribute values aren't restricted to constants. You can also provide a +function, for example:: + + (let ((clock (make-clock))) + (at washM + (lambda () + (* 50 + (+ 1 (sin (* 2 (elapsed-time clock)))))))) + +That's obvious quite complicated, so use the functions in module ``(starlet +effects)`` instead. For a sine wave once every 2 seconds (0.5 Hz) ranging +between zero and 100%:: + + (at washM (sinewave 0.5 0 100)) diff --git a/docs/cue-list.rst b/docs/cue-list.rst new file mode 100644 index 0000000..9a83ca0 --- /dev/null +++ b/docs/cue-list.rst @@ -0,0 +1,205 @@ +======================= +Cue lists and playbacks +======================= + +Anatomy of a cue +================ + +A cue is formed by associating a lighting state with a *transition effect*. +As an example, here is cue 4.3 representing a 4 second crossfade to a dim +lighting wash:: + + (cue 4.3 ;; <---- the cue number + + (lighting-state ;; + (at washL washR 30) ;; lighting state + (at washM 40)) ;; + + (crossfade 4)) ;; <---- transition: 4 second crossfade + +The simplest transition effect is ``(snap)``, which produces a hard zero-time +transition to the cue. The usual one is ``crossfade``, which produces a smooth +fade in the time you specify (in seconds). It gives you a lot of control, for +example, to fade intensities up in 4 seconds but down in 2 seconds:: + + (crossfade 4 2) + +To delay the up fade part by 2 seconds relative to everything else:: + + (crossfade 4 #:up-delay 2) + +To delay the down fade part, use ``#:down-delay``. To control the fade times +for non-intensity parameters, use ``#:attr-time`` and ``#:attr-delay``. +Putting it all together for a complicated crossfade:: + + (crossfade 3 4 + #:up-delay 2 + #:attr-time 1 + #:attr-delay 1.5) + +You can write your own transition effects, if you want some other kind of +transition. Documentation pending, but look at snap-transition.scm and +crossfade.scm for some examples. + + +Cue lists +========== + +A cue list is simply a list of cues. For example:: + + (cue-list + + (cue 0.5 + ;; Tab warmers + (lighting-state + (at washL washR 30) + (at washM 40)) + (snap)) + + (cue 0.8 + ;; Blackout + (lighting-state) + (crossfade 6)) ;; 6 second fade + + (cue 1 + ;; Act 1, Scene 1 + (lighting-state + (at front-wash 80) + (at moverL 'colour (cmy 21 0 0))) + (at moverL 25) + (crossfade 3)) + + (cue 2 + (lighting-state + (at washM 100)) + (crossfade 3 4)) ;; Separate up/down fade times + + (cue 2.5 + (lighting-state + (apply-state home-state) + (at moverR 100)) + (crossfade 2))) + +Just so you know, the cue list is represented internally as a Scheme *vector*, +not a real list. + + +Playback objects +================ + +The cue list doesn't do anything on its own. To actually see the contents on +the stage, it needs to be loaded into a playback. In practice, the best way to +work is to put the cue list in a file on its own and create the playback with +a reference to that file:: + + (define pb + (make-playback + #:cue-list-file "shows/my-show.qlist.scm" + #:recovery-file "recovery.q")) + +The ``#:recovery-file`` is optional but highly recommended, discussed below. + +Once the playback has been created like this, if you change the cue list file +then you can re-load it:: + + scheme@(guile-user)> (reload-cue-list! pb) + $8 = cue-list-reloaded + +If the modifications to the cue list file involved the currently active cue, +the state shown on the stage will *not* be updated until you say so, with:: + + (reassert-current-cue! pb) + +The playback object shows useful information when printed:: + + scheme@(guile-user)> pb + $1 = #< state: ready current-cue: 43.0 next-cue: 44.0> + +For completeness, know that you can also create a playback like this:: + + (define my-cue-list + (cue-list + (cue ...))) + + (define pb (make-playback #:cue-list my-cue-list)) + +However, this makes it much harder to make subsequent changes to the cue list. + + +Running cues +============ + +To rapidly jump (with a snap transition) to a cue, use ``cut-to-cue-number!``. +To run a cue using the transition specified in the cue list, use +``run-cue-number!``:: + + (cut-to-cue-number! pb 1) + (run-cue-number! pb 4) + +Calling ``go!`` will run the next cue in the cue list:: + + (go! pb) + +Playbacks also implement the other familiar operations: + +* ``(stop! pb)`` - immediately pause any running cue. The next call to + ``go!`` will continue it. +* ``(cut! pb)`` - run the next cue, using a snap transition regardless of what + the cue specifies. +* ``(back! pb)`` - go backwards one step in the cue list, using a snap + transition. + + +Tracking +======== + +By default, non-intensity parameters will "track" from one cue into the next +cue. That helps to avoid unexpected parameter changes, e.g. a moving light +changing position while it dims. If you run cues *out of order*, the result +will be the same as if you'd run the cues *in order* from the start, to get to +the cue you wanted. If you're lucky enough to have never encountered a system +that works any other way, just know that it works the way you'd expect it to +work in a theatrical system. + +If you additionally want to track *intensities* into a cue, use +``#:track-intensities``:: + + (cue 1 + (lighting-state + (at front-wash 80)) + (crossfade 3)) + + (cue 2 + (lighting-state + (at spotC 100)) + (crossfade 3) + #:track-intensities #t) + +In this example, cue 2 will include ``spotC`` at full intensity, **and** +``front-wash`` at 80% intensity. + + +Fixture presetting ("auto move while dark") +=========================================== + +Starlet tries as hard as it can to get non-intensity parameters into the right +state before running a cue. In other words, it makes a big effort to avoid the +audience seeing moving lights actually move. If a fixture's ``intensity`` +parameter is zero after running a cue, Starlet will set all its non-intensity +parameters to the values in the next cue. Of course, if a non-intensity +parameter changes while the intensity is non-zero, the audience will see the +move! + + +The recovery file +================= + +The purpose of the playback recovery file is to make a rapid recovery after a +crash (not that there will be any, of course!). If the file specified by the +``#:recovery-file`` keyword argument to ``make-playback`` exists when the +playback is created, the playback will immediately jump to the cue number in +the file. Whenever you run (or jump to) a cue, the cue number in the file will +be updated. If you don't use a recovery file, the playback will revert to cue +zero on creation and you'll have to use ``cut-to-cue-number!``. That will +create a blackout of a few seconds while you figure out the right cue number to +pick up from where things went wrong. diff --git a/docs/new-fixture.rst b/docs/new-fixture.rst index 2c0771d..408f2ab 100644 --- a/docs/new-fixture.rst +++ b/docs/new-fixture.rst @@ -99,7 +99,7 @@ Worked example ============== Here is an annotated version of the definition for the -`Stairville Octagon Theatre CW/WW fixture `_ +`Stairville Octagon Theatre CW/WW `_. The channels for this fixture are: 1. Cold LED intensity (0-255 min-max) diff --git a/docs/patching.rst b/docs/patching.rst index aaf25ff..37c2f2e 100644 --- a/docs/patching.rst +++ b/docs/patching.rst @@ -14,8 +14,7 @@ to patch a simple dimmer with DMX address 32 on universe 4:: (patch-fixture! my-dimmer 32 #:universe 4) Universe numbering starts from zero (consistent with OLA's numbering), and -channel numbering starts from 1 (consistent with every other system on the -planet). +channel numbering starts from 1. After the above, the symbol ``my-dimmer`` will be bound to an object representing the dimmer:: @@ -26,6 +25,16 @@ representing the dimmer:: Intelligent fixtures should go to their home positions immediately after being patched. +Note that you can give a fixture multiple names. For example, if the spotlight +you use for a throne (``throne-spot``) is re-used to light a table:: + + (define table-spot throne-spot) + +This leaves the door open for replacing ``table-spot`` with a separate fixture +later on, if the re-usage doesn't work out as you expected. In that case, +after rigging the new fixture, simply replace the above ``define`` call with a +new call to ``patch-fixture!``. + Lists of fixtures ================= @@ -34,22 +43,22 @@ Starlet fixture objects are just normal `GOOPS `_ objects. You can do normal Scheme-y things with them, such as making lists of them:: - (define red-backlight (list backlight-red-usl - backlight-red-usr - backlight-red-dsl - backlight-red-dsr)) + (define red-backlight + (list backlight-red-usl + backlight-red-usr + backlight-red-dsl + backlight-red-dsr)) Procedures such as ``at`` work with these lists in the same way that they work on individual fixtures:: (at red-backlight 100) -See the documentation about setting attributes for more information on this -topic. +See ``_ for more information about ``at``. -Multiple fixtures with similar names -==================================== +Patching multiple fixtures at once +================================== At this point, you might be tempted to create a standard file which defines all the fixtures in your venue, naming them ``dimmer1``, ``dimmer2``, ``dimmer3`` @@ -65,49 +74,33 @@ use descriptive names for your fixture objects. When using Starlet, you shouldn't need to constantly look up fixture names (or worse, numbers) in a lighting plan. Instead, give your fixtures names which represent what they do, for example: ``balcony-front-warm``, ``followspot`` or ``throne-spot``. -Note that you can give a fixture multiple names. For example, if the spotlight -you use for a throne (``throne-spot``) is re-used to light a table:: - - (define table-spot throne-spot) -This leaves the door open for replacing ``table-spot`` with a separate fixture -later on, if the re-usage doesn't work out as you expected. In that case, -simply replace the above ``define`` call with a new call to ``patch-fixture!``. - - -Patching multiple fixtures at once -================================== - -Despite the above, there will probably be times when you have a large number of -fixtures that should be treated to a greater extent as one entity. For this -situation, use ``patch-many!``, which patches a series of fixtures of the same -type. For example, to create eight dimmers with DMX addresses numbered 2, 4, -6... :: - - (patch-many! foh-warm '(2 4 6 8 10 12 14 16)) - -Symbol ``foh-warm`` will be bound to a list containing the fixture objects:: +What you *can* do, however, is to create a list of fixtures all at once. The +individual fixtures in the list won't have their own names, so this is meant +for situations where you mainly want to control the fixtures as a group. For +example, to create eight dimmers with DMX addresses numbered 2, 4, 6... :: + scheme@(guile-user)> (patch-many! foh-warm '(2 4 6 8 10 12 14 16)) scheme@(guile-user)> foh-warm - $2 = (#< 7f6da7c3dc00> #< 7f6da7c3db80> + $1 = (#< 7f6da7c3dc00> #< 7f6da7c3db80> #< 7f6da7c3db00> #< 7f6da7c3da80> #< 7f6da7c3da40> #< 7f6da7c3d9c0> #< 7f6da7c3d940> #< 7f6da7c3d8c0>) + scheme@(guile-user)> (at foh-warm 85) -Instead of explicitly specifying the list of addresses, you could use ``iota``. -For example, this time putting the dimmers on universe 3:: +To address a fixture individually from the list, you would need to use +``list-ref``. This is a little clumsy, but as mentioned above should be a rare +exception:: - (patch-many! foh-warm (iota 8 2 2) - #:universe 3) + (at (list-ref foh-warm 2) 85) -Hopefully obviously, the fixtures in one ``patch-many!`` call all need to be on -the same DMX universe. +Instead of explicitly specifying the list of addresses in ``patch-many!``, you +can use ``iota`` to generate the list of addresses. The following call has the +same effect as the example above, except this time the dimmers are on universe +3 instead of 0:: -For the rare situation when you need to control a single fixture from the list -separately to the others, create a new binding to an item from the list:: - - (define forestage-warm-patch (list-ref foh-warm 2)) + (patch-many! foh-warm (iota 8 2 2) + #:universe 3) -As before, this leaves an easy way to install a dedicated fixture for the -purpose, should it later become necessary, without having to re-write your -entire lighting program. +Note that the fixtures in one ``patch-many!`` call all need to be on the same +DMX universe. diff --git a/docs/physical-control.rst b/docs/physical-control.rst new file mode 100644 index 0000000..1305673 --- /dev/null +++ b/docs/physical-control.rst @@ -0,0 +1,4 @@ +================================== +Using physical controls (MIDI etc) +================================== + -- cgit v1.2.3