The arrangement in the session not only determines when media is played, but also how the media streams are routed from clips to outputs, as well as the settings that govern processing along this pathway. Two topics that look separate at first sight — and turn out not to be.
|
This page consolidates design decisions that have been evolved over a long period of time and recorded in widely scattered locations — the development wiki, the issue tracker and personal working notes. Knowledge-Technology (»AI«) was used to collect and correlate that material. |
Those who have worked with media applications will be familiar with the following observations:
Often you cannot take hold of a fader while an automation curve is running on it. The curve owns the control. In practice this forces automation work towards the very end of a project, and turns last-minute global adjustments into a nightmare.
Sound and image of a clip are “linked”, and the link is a thing that can break. Every application invents its own machinery to keep the two together, and every editor knows the machinery by the way it fails.
The viewer shows one thing, the export produces another, because the display path and the render path are separate mechanisms that happen to be configured alike, while they should not.
The audio is “Mono, Stereo or 5.1”, as these were the cases that someone deemed “standard”. Anything else is either impossible or a special mode.
The vertical order of the tracks decides which image is composited on top. Content therefore has to be arranged by technical necessity rather than by whatever order would suit the work.
And a general one: Something has shifted or sounds different, and it is not possible to identify the reason for this subtle change.
None of these is a defect. Each one is the result of premature decisions taken at an early stage in the conception of the application, at a time when the consequences looked local and harmless. This page describes the decisions Lumiera takes instead — what they imply, and cost.
In the High-level Model the user does not connect anything. Objects are placed, and the connections are derived from the placements by the Builder — and the latter not only compiles the structure laid out in the session and translates it into chains of Render Notes, but also applies a set of Rules while doing so. These rules are configurable.
A Placement attaches a media object into the session and carries a list of constraints. These resolve at least two dimensions: when the object appears, and where its output goes. The second is what concerns us here. A placement may carry a plug — that is a connection request naming an output designation. When no plug is given, the Builder searches the enclosing scopes, and finally applies a generic rule, matching by media stream type.
The counterpart is a claim: an element may assert that it constitutes such a named designation. Output and routing will only happen where a claim and a use coincide. A designation that nobody claims connects to nothing; a claim that nobody uses produces nothing. This symmetry is deliberate — it means that no part of the model can quietly become an output, and that routing can be expressed without any element needing to know who will listen.
Two consequences are worth drawing out at once.
The first is that in the default configuration there is only one designation: the »master output«. It is supplied by default rules rather than being defined in the session, and everything not routed otherwise goes there. The separation into video output and sound output is then performed by the Builder, by observing which kinds of media are actually present. Video and sound are not two subsystems that have been made to look alike; they are one mechanism, and their separation is a consequence of typing.
The second is that a routing decision taken high in the fork (≙ tree of tracks) applies to everything below it, unless some placement further down states otherwise. Routing is therefore inherited in the same way as everything else a placement determines — and it can be inherited selectively: a rule may bind to a tag in the media, causing the sound of all tagged clips to be routed into a separate subgroup while their video stream continues to follow the common path, because the stream type acts as a selector for which designation rules apply.
Together the arrangement rules described here create a structural vocabulary. And whilst this structural vocabulary has been deliberately kept to a minimum, it can be applied wherever appropriate. A pipe is a linear chain of processing steps with an entrance and an exit — it emerges whenever effects and transitions attach to some other element by placement, and the chain is built in the order in which they are placed. Pipes occur as the local chains belonging to a clip, and as the global pipes of a timeline, which collect and mix like the subgroups and masters of a sound mixing desk. An effect stack may equally be attached at a fork, applying to everything within it, or at a subgroup bus, applying to the subgroup as a whole — and a subgroup may in turn be routed onward to another, by adding a plug into its placement.
Describing the signal flow in terms of these pipes imposes some defining structural properties: First and foremost, a pipe is linear. Anything that branches happens between pipes, not inside one. Only when the output from pipes is combined into another designation, a mixing or overlaying stage emerges. This is not a restriction rationalised afterwards, it is what makes the arrangement presentable in compact form. An effect stack or a strip in a mixer is the direct depiction of a linear chain.
Furthermore, a pipe is homogeneous in its stream type, and no conversion is allowed to happen within it. Conversions occur at the junctions between pipes, and only where the routing rules permit them: Wiring a monophonic effect into a pipe carrying an Ambisonics feed is not a small mismatch to be papered over — the channels of such a sound field are not separate signals but coefficients of one spatial encoding, and the operation of a monaural effect has no meaning in that context. It is reported as an error. Decoding that same field into a stereo bus however, intended for headphones, is a legitimate rendering operation, and it belongs at the junction where it can be seen.
This is also why a clip carrying image and sound is not a special construction. It anchors two pipes at the same point, and effects attached to it are sorted by the kind of media they apply to. There is no link to maintain between picture and sound, because there was never a division to bridge: mixed media multichannel material is the ordinary case, and material with a single stream is the exception.
Lumiera does translate everything into a graph of processing nodes. The question is whether that graph is what the user should work on, directly. The answer is no, and the reason is not distaste for node editors.
The vision document names a medium level of abstraction as a fundamental force of the design: the user manipulates placements, parameters, masks and layering directly — which is comparatively low-level and deliberately so — while being shielded from technical detail such as format conversion or access to individual channels. A node graph sits below that line. It exposes exactly what the principle sets out to conceal, and it invites the user to maintain by hand a structure that the Builder can derive. Feature-driven applications on the other hand, where one presses the button and the software decides autonomously, would operate way above that line of medium abstraction. And thus the structural vocabulary of Lumiera, the pipes, buses and placements are situated in that middle ground where a direct connection to the medium is still given.
And there is a practical argument, pointing into the same direction. Anyone who works seriously with node-based compositing will learn to impose discipline on the graph voluntarily — a grouping and naming, an arrangement to keep the subtrees self-contained — because an unstructured graph becomes unworkable at scale. The structure Lumiera prescribes is the structure practitioners adopt anyway. What is given up is the freedom to build arbitrary topologies; what is gained is that the arrangement stays legible, and that the same arrangement can be presented as a mixer rather than as a node tree.
However, where genuinely graph-like composition is desired, the model already provides the necessary expressive means: For one, the routing plugs can be added anywhere, even in the middle of a pipe, so that sidechains can be formed. And furthermore, a sequence bound into another sequence appears there as a virtual clip, with its own internal arrangement, behaving from the outside like any other media. The recursion is already present, and it isolates the complexity in the same way that practitioners do by hand.
Establishing a connection does more than join two points.
It creates degrees of freedom that did not exist before.
Connecting a monaural source into a spatial sound bus creates the possibility of placing that source in space: azimuth, elevation, distance, directivity. Placing one image on top of another will create an overlay mode and layering order. A connection carrying several multicam views may create a view selection. Which degrees of freedom appear is determined by the stream types meeting at that junction — and once those new dimensions exist, they are ordinary placement dimensions, resolved and inherited like any other.
In most software these forms of connectivity are provided, albeit in the form of distinct features, located in unrelated parts of the application, implemented separately, with asymmetric vocabulary. In Lumiera they are just one slot in the model whose available settings are derived from the type of what meets there: Summation with transparency is only the default way of overlaying two video streams, not the only one. Image compositing has a set of blend modes — the formulation introduced by the GIMP became a de-facto standard and was adopted by other applications. Masking provides the alpha input for these stream combinators; 3D images have a depth of stereoscopic window; sound has panning laws, and spatialisation schemes.
Which leaves an obvious question hanging. These degrees of freedom are control values — a position in space, an opacity, a blend mode — and they have to come from somewhere.
In Lumiera, a parameter is not a just stored value.
It is a data item that gets resolved when it is needed.
What a parameter carries is a disposition: a type together with a statement of how its value is to be obtained. The type has two aspects. Its domain fixes which values are meaningful at all — a value type, a range, a set of symbols, a structure — and it is the builder’s business to guarantee that whatever is delivered lies within it. The scale of the type fixes what a value means: decibels rather than a factor, seconds rather than frames. Scale is treated as part of the type and not as a matter of display, because a logarithmic quantity is a different quantity: it steps differently under the hand, and, as will be seen in a moment, it combines differently.
The second aspect is the provision of a parameter — where the value comes from. It may be a fixed value; it may be pulled from a function of time; it may come from a control being operated, or from a stream of external data. What matters is that the consumer of the parameter cannot tell which. A constant is simply the case where the function is trivial.
That is the point at which the first of the annoyances above dissolves. Several sources may contribute to one parameter, and the placement of each contribution states whether it replaces what the enclosing scope supplies or combines with it. Combining needs a joining operator, and the permissible operators follow from the domain — which is why scale belongs to the type: multiplying in a linear scale is adding in a logarithmic one, and a mechanism that treated scale as presentation would leave the question undefined. A contribution also states where it stands relative to the local one, because these operators do not generally commute.
So a gain may carry a value the user adjusts by hand, and a curve varying over time, and a correction applying to a whole group — all at once, without any of them seizing the control. And a scene-wide colour correction combined with a local adjustment is one transformation computed once, rather than two effects in series quantising the image twice.
This is also where Automation belongs, and it is deliberately mentioned this late. Automation is not a mechanism of its own; it is one provision among several — the case where the value is a function of time, typically defined mathematically as some kind of Spline, or step-wise interpolation. The habit of treating it as a separate faculty, a recording of knob movements replayed by machinery bolted on top of the mixer, is the source of much of the trouble it causes elsewhere: such a recording is attached to the surface of the application rather than to the material, and drifts against the material as soon as anything is edited. Here an automation source is a model object like any other, attached by placement, and therefore follows the clip or effect it belongs to whenever these move.
Taken together, the parameters form a second network spanning the processing, beside the flow of media data. Its practical significance is that it marks out what can change without rebuilding anything: the structure of the media graph is fixed when it is built, while the values flowing through the parameter network vary freely. A monitoring point that can be switched during playback is of this kind, or a mute toggle — the alternatives were built in advance, and the switching is a parameter.
The same plot is recounted on both halves of this page…
A specification is placed into a scope. It names what it wants rather than what it connects to. The Builder resolves it, searching outward through the enclosing scopes, constrained by type, falling back on rules where nothing was stated. Where several things arrive at the same place, they combine according to a law that the type supplies and the placement selects. Nothing is stored that could be derived, and nothing is derived that could not be overridden.
Read that as a description of signal flow and it is the routing model. Read it as a description of control values and it is parametrisation. The two are not analogous by coincidence: routing and parametrisation meet at the junctions, because it is the act of connecting that brings the parameters into existence.
A third recurrence is beginning to show, though it should be stated with more caution
than the other two. Stream types, placements and parameters are each turning out to
have the same construction: a prototype naming a role, an open collection of
determinations, and a gap between the two which the rules and the project’s own
configuration are free to fill. A stream prototype says spatial-sound without
fixing what that entails; a placement prototype says “anchored to its neighbour”
as a bundle of constraints; a parameter prototype says “a gain” or “a colour”.
This is convenient for the implementation, but its real value is elsewhere: a
prototype is the human face of a rules system. Not everybody wishes to think in
rules, but everybody understands a named thing that behaves as expected and can be
adjusted when it does not.
None of this is an invention out of the blue. Both movements follow from forces stated in the vision document, formulated years before either was worked out in detail: that the building blocks carry types which say what may be combined with what, and that within those constraints any combination is possible; and that the level of abstraction is chosen as a middle ground, with project-specific conventions taking the place of hard-wired global ones. Routing and parametrisation are what those forces look like when applied to signal flow and to control.
There remains the last of the annoyances — not knowing what decided something. Because connections and values are resolved rather than stored, every one of them has a derivation; and because the session is maintained as a log of what happened, that derivation can be recorded. The question “why is this here?” is therefore answerable in principle, which is a stronger position than most applications are in. Turning that into something a user can actually ask is a matter of design still to be done.
This is a design in progress, and several of the concepts described here are firmer at the top than at the bottom.
The outer structure seems clear: a kind of media at the top, and at the bottom an implementation type belonging to whichever media library provides the material. Between them lies an open layer, holding the distinctions practitioners actually make — “this is high-quality footage”, “this is ambience” — and it is largely uncharted. It is also the natural home for tagging of source material, which would then serve organisation, routing and typing at once. This area will be settled by integrating real media libraries and seeing what is needed, not by deduction.
Combining contributions to one parameter rather than applying two effects in sequence works only where the operations compose. Many do not: lookup tables, anything that clips or saturates, anything whose order is observable. Where they do not, a separate processing step is genuinely required, and part of the work is knowing which case one is in.
Establishing a grading arrangement, or any similar setup, means bringing new content into the model at several defined places at once. There is as yet no mechanism for that. It is at least three problems: recognising where the structure attaches, deciding whether the result is materialised as ordinary model content or re-derived on each build, and reconciling later local edits with a subsequent change to the template. The second is the crux, since materialising gives up the connection to the template while re-deriving gives up the ability to edit the result.
Parameter sources need to designate their target as indirectly as media routing designates its own, and the matching must be dependable. Much of the fine detail of the system will live here.
Some work demands that the application refuse rather than accommodate — that it decline a conversion instead of performing a convenient one. Other work wants the opposite. This is a matter of configuration, which is assembled in layers with the project supplying its own; but it is unlikely to be a single setting, and the work of identifying where strictness matters has not been done.
Beyond that, three things are simply untouched: what takes over the role of muting or soloing a track once the global order of tracks is given up; how automation defined over nominal time behaves when material is retimed or nested; and how a model that routes by designation is to be exchanged with formats that assume explicit wiring between numbered tracks.
A design at this level of complexity is only worth anything if it can be approached in stages, and the design of Lumiera proceeds in a way so that it can be.
The turning point is that the code asks at every point where a decision is required, rather than containing the decision. What answers the question can actually begin as something fixed and unremarkable and evolve into a rules system later, without the model or the structure of the Builder being disturbed. In the same spirit, translating the model into a processing graph directly, step by step, is a correct first implementation and not a compromise: improving the layout of that graph — deciding where conversions physically belong, what may share a working colour space, what could be handed to other processing hardware — is a separate stage acting on the result, in the way that an optimising pass acts on generated code. A compiler without optimiser still emits correct programs.
What must not be deferred however is the recording of events. As long as every resolution is entered in the log, the reasoning behind it remains available, and the parts that are provisional can be replaced without the sessions made with them becoming unreadable.