From 63fa386cbc7eb590847cc3ffced06ad6efed6946 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 18 Jun 2023 12:20:29 +0200 Subject: Update docs/physical-control.rst --- docs/physical-control.rst | 221 ++++++++++++++++++++-------------------------- 1 file changed, 97 insertions(+), 124 deletions(-) diff --git a/docs/physical-control.rst b/docs/physical-control.rst index 43eb510..743ed89 100644 --- a/docs/physical-control.rst +++ b/docs/physical-control.rst @@ -1,128 +1,101 @@ -================================== -Using physical controls (MIDI etc) -================================== +================================= +Using physical controls (via OSC) +================================= -Start MIDI control by creating a controller object. You need to give the -device node for the controller, and the MIDI channel to use:: +Starlet's OSC implementation uses liblo via Guile-OSC. You can use Guile-OSC +procedures directly for many things. Starlet provides utilities for +higher-level control primitives. - (define controller - (make-midi-controller "/dev/snd/midiC1D0" 14) +Start OSC by creating a server thread. This will receive OSC method calls from +other programs. You can customise the port number and protocol (UDP vs TCP) as +you need:: -To send a MIDI "note on" command, e.g. to light an LED, use ``send-note-on``. -There is also ``send-note-off``:: + (define osc-server (make-osc-server-thread "osc.udp://:7770")) - (send-note-on controller 25) - (send-note-off controller 25) - -Buttons -======= - -You can assign a procedure to be called when a MIDI button is pressed:: - - (register-midi-note-callback! - controller - #:note-number 25 - #:func (lambda () - (reload-cue-list! pb) - (reassert-current-cue! pb))) - -Let's say you want to use a MIDI button to quickly select all the fixtures in -your front wash. You could assign a procedure with a call to ``sel`` inside -(see ``_ for more about ``sel``). However, there is a -helper procedure in module ``(starlet midi-control button-utils)``:: - - (select-on-button controller 32 - (list washL washM washR) - #:ready-note 68) - -The ``#:ready-note`` is just a note to send, e.g. to light up an LED to -indicate that the button is active - leave it out if you don't need it. Use -``#f`` as the fixture name to make a "deselect" button. - -There are similar utilities for creating *go*, *stop* and *back* buttons -(see ``_):: - - (make-go-button controller pb 12 - #:ready-note 20 - #:pause-note 16) - - (make-stop-button controller pb 24 - #:ready-note 24) - - (make-back-button controller pb 28 - #:ready-note 28) - -With ``make-go-button``, the ``pause-note`` will be lit when the playback has -been paused with ``stop!`` (see ``_), otherwise the -``ready-note`` will be lit. On my controller (Allen and Heath XONE:K2), these -notes light the same button in different colours. - -The ``ready-note`` for ``make-stop-button`` will be lit when a cue is running, -i.e. when the playback can usefully be stopped. - -With ``make-go-button``, you can additionally use -``#:min-time-between-presses`` to set a minimum waiting time (in seconds) -between activations. This sometimes helps with jittery fingers. The default -is 0.2 seconds. - - -Putting a state on a fader -========================== - -To simply assign a state to a fader:: - - (state-on-fader controller 19 - (lighting-state - (at front-wash 100) - (at domeL domeR 100))) - -The fader's control of the state will be completely separate to other states, -i.e. it will not affect the contents of the programmer. The programmer state -will have priority over states on faders. - - -Control map -=========== - -You can associate MIDI controls with fixture parameters, such that when a -fixture is selected, those controls can be used to change the parameters in the -programmer state. Here's an example:: - - (set-midi-control-map! - controller - (fader 16 intensity #:congruent 108 #:incongruent 72) - (jogwheel 0 pan #:active 124) - (jogwheel 1 tilt #:active 125) - (fader 4 (colour-component-id 'cyan) #:congruent 120 #:incongruent 84) - (fader 5 (colour-component-id 'magenta) #:congruent 121 #:incongruent 85) - (fader 6 (colour-component-id 'yellow) #:congruent 122 #:incongruent 86) - (fader 7 colour-temperature #:congruent 123 #:incongruent 87)) - -Use ``fader`` for MIDI *continuous control* parameters (CCs), which might -physically correspond to faders or rotary potentiometers with a minimum and -maximum value (distinct from *jogwheels* - see below). You need to give the -MIDI CC number, then the parameter which should be controlled. To control a -single component of the colour, use ``colour-component-id`` as shown in the -example. - -Faders (and potentiometers) are somewhat awkward, because there's no guarantee -that the fader will be in the position corresponding to the current value of -the parameter it controls. To avoid jumps, Starlet will only start changing -the parameter value once the fader passes through the correct value. This -means that you might have to move the fader to "pick up" the value along its -way. The ``congruent`` and ``incongruent`` values are optional, but highly -recommended. They give the note numbers corresponding to two LEDs, one of -which will be lit when the fader position is "congruent" with the underlying -parameter value and moving the fader will change the value. At other times, -the ``incongruent`` LED will be lit to show that the fader needs to "pick up" -the value. Starlet will take care of getting this right even when you select -multiple fixtures at once with different values, or when the underlying value -is changed by some other means. - -This is somewhat awkward, but on the other hand potentiometers are cheap and -your controller is likely to have a lot of them. The alternative is to use -``jogwheel``, which is for CCs which don't give a continuous value but rather -either 0 or 127 to increase or decrease the value respectively. This avoids -the whole "congruence" issue. For ``jogwheel``, you only need to give the CC -number, the attribute to control, and an optional note to use for lighting an -LED to indicate when the parameter is active. +You'll also need to create an OSC address object for each external program that +will receive OSC calls from Starlet:: + + (define controller (make-osc-address "osc.udp://localhost:7771")) + +Now, you can call external OSC methods like this:: + + (osc-send controller "/my/controller/led/4/set-colour" 'red) + +You can also create methods of your own, like this example which reloads a cue +list on a button press:: + + (add-osc-method + osc-server + "/controller/buttons/30/press" + "" + (lambda () + (reload-cue-list! pb) + (reassert-current-cue! pb))) + +See the manual for `Guile-OSC `_ for more +information about this part. + + +High-level controls +=================== + +The functions described below expect the high-level OSC interface as +implemented in `x1k2-midi-osc-alsa `_. +See the manual for more information about the protocol. The sections below +describe how to use them in Starlet. Since they need bi-directional +communication, you have to provide an OSC server and the OSC address for the +controller. + + +Selection buttons +----------------- + +This gives you a button that adds a fixture or group to the selection when +pressed. If the button has LEDs, they will be lit orange when selected, and +red otherwise:: + + (osc-select-button front-wash osc-server controller-addr "/controller/buttons/18") + + +Playback controls +----------------- + +This lets you control a playback object with buttons, which will light up to +show when a cue is running. The buttons are (respectively, in argument order) +go, stop and back:: + + (osc-playback-controls pb osc-server controller "/controller/buttons/102" "/controller/buttons/32" "/controller/buttons/28") + + +States on fader (submasters) +---------------------------- + +You can put an entire state on a fader. Non-intensity parameters will be +asserted only when the fader is up (non-zero). If it's not already there, the +fader will need to be picked up at the bottom of its run:: + + (osc-state-fader osc-server controller "/controller/faders/4" + (lighting-state + (at mhL mhR colour (rgb 40 20 70)) + (at mhL mhR 100) + (at front-wash 100) + (at domeL domeR 100))) + + +Parameter encoders and potentiometers +------------------------------------- + +These give you physical control of an individual parameter in the programmer +state. LEDs will be used to indicate whether any of the currently selected +fixtures have the named parameter. + +The simplest form is an encoder. This increases or decreases the parameter +value when turned. Push and turn to make finer adjustments:: + + (osc-parameter-encoder intensity osc-server controller "/controller/encoders/102") + + +Potentiometers are the same, but include a soft pickup mechanism because the +physical position might not match Starlet's view of the position:: + + (osc-smart-potentiometer color-temperature osc-server controller "/controller/potentiometers/4") -- cgit v1.2.3