X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=theme.rst;h=8dbaf80b06b14d2aa09758348f2c0077b9b49a06;hb=HEAD;hp=2e8b6663b0ccddd05fe1314502ff9c5d2cf040f5;hpb=c968d8319a8f77ed3777094d824690904cd0f43b;p=nageru-docs diff --git a/theme.rst b/theme.rst index 2e8b666..8dbaf80 100644 --- a/theme.rst +++ b/theme.rst @@ -1,14 +1,6 @@ The theme ========= -**NOTE**: Nageru 1.9.0 made significant improvements to themes -and how scenes work. If you use an older version, you may want -to look at `the 1.8.6 documentation `_; -themes written for older versions still work without modification in -1.9.0, but are not documented here, and you are advised to change -to use the new interfaces, as they are equally powerful and much simpler -to work with. - In Nageru, most of the business logic around how your stream ends up looking is governed by the **theme**, much like how a theme works on a blog or a CMS. Most importantly, the theme @@ -303,18 +295,28 @@ The theme should return a CSS color (e.g. “#ff0000”, or “cyan”) for each channel when asked; it can vary from frame to frame. A typical use is to mark the currently playing input as red, or the preview as green. -And finally, there are two entry points related to white balance:: + +.. _white-balance: + +White balance +............. + +Finally, there are two entry points related to white balance. The first one +is:: Nageru.set_supports_wb(2, true) - function set_wb(channel, red, green, blue) If the first function is called with a true value (at the start of the theme), the channel will get a “Set WB” button next to it, which will activate a color -picker. When the user picks a color (ostensibly with a gray point), the second -function will be called (with the RGB values in linear light—not sRGB!), -and the theme can then use it to adjust the white balance for that channel. -The typical way to to this is to have a *WhiteBalanceEffect* on each input -and set its “neutral_color” parameter using the “set_vec3” function. +picker, to select the gray point. To actually *apply* this white balance change, +add the white balance element to the scene:: + + scene:add_white_balance() + +The white balance effect will automatically figure out which input it is +connected to, and fetch its gray point if needed. (If it is connected to +e.g. a mix of several inputs, such as a camera and an overlay, you will need to +give the input to fetch white balance from as as a parameter.) More complicated channels: Composites @@ -399,11 +401,21 @@ crop is. If so, you can do this:: resample_effect:always_disable_if_disabled(crop_effect) +Also, you can disable an optional effect if a given other +effect is *enabled*:: + + overlay1_effect:promise_to_disable_if_enabled(overlay2_effect) + overlay2_effect:promise_to_disable_if_enabled(overlay1_effect) + +Note that the latter is a promise from the user, not automatic disabling; since +it is mostly useful for mutual exclusions, Nageru wouldn't know which of the +two to disable. (If you violate the promise, you will get an error message at +runtime.) It can still be useful for reducing the number of alternatives, though. + For more advanced exclusions, you may choose to split up the scenes into several -distinct ones that you manage yourself; indeed, before Nageru 1.9.0, that was -the only option. At some point, however, you may choose to simply accept the -added startup time and a bit of extra RAM cost; ease of use and flexibility often -trumps such concerns. +distinct ones that you manage yourself. At some point, however, you may choose +to simply accept the added startup time and a bit of extra RAM cost; ease of +use and flexibility often trumps such concerns. .. _menus: @@ -498,11 +510,60 @@ effect alternatives. In particular, you may want to disable scaling if the frame is already of the correct resolution. +Audio control +------------- + +Before you attempt to control audio from the theme, be sure to have read +the documentation about :doc:`audio`. + +The theme has a certain amount of control over the audio +mix, assuming that you are in multichannel mode. This is useful in particular +to be able to set defaults, if e.g. one channel should always be muted at +startup, or to switch in/out certain channels depending on whether they are +visible or not. + +In particular, these operations are available:: + + # Returns number of buses in the mapping. + local num_buses = Nageru.get_num_audio_buses() + + # Gets the name from the mapping. All indexes start at zero, + # so valid indexes are 0..(num_buses-1), inclusive. + local name = Nageru.get_audio_bus_name(N) + + # 0.0 is zero amplification, as in the UI. Valid range is + # -inf to +6.0, inclusive. + local level = Nageru.get_audio_bus_fader_level_db(N) + set_audio_bus_fader_level_db(N, level) + + # Similar as the above, but valid range is -15.0..+15.0 (dB). + # Valid bands are Nageru.EQ_BAND_{BASS, MID, TREBLE}. + local eq_level = Nageru.get_audio_bus_eq_level_db(N, Nageru.EQ_BAND_BASS) + Nageru.set_audio_bus_eq_level_db(N, Nageru.EQ_BAND_BASS, level) + + # A boolean. Does not affect the bus levels set/returned above. + local muted = Nageru_get_audio_bus_mute(N) + Nageru_set_audio_bus_mute(N, false) + +Note that any audio operation is inherently unsynchronized with the UI, +so if the user reduces the number of audio buses while +the theme tries to access one that is going away, you may get unpredictable +behavior, up to and including crashes. Thus, you will need to be careful +with such operations. + +Also, you cannot do anything with audio before the first *get_scene()* call, +since the audio mixer is initialized only after the theme has been loaded and +initialized. Thus, for things that should be done only the first frame, the +recommended method is to put code into get_scene() and have a guard variable +that makes sure it is only run +once, ever. + + Overriding the status line -------------------------- Some users may wish to override the status line, e.g. with recording time. -If so, it is possible (since Nageru 1.9.1) to declare a function **format_status_line**:: +If so, it is possible to declare a function **format_status_line**:: function format_status_line(disk_space_text, file_length_seconds) if file_length_seconds > 86400.0 then