Building a derived channel from a graph of source nodes, operations and one output, and how the graph is evaluated. Martino Ferrari Math channels

A math channel is a signal computed from other signals. You build it as a small graph — source nodes, operations, one output — and udpscope then treats the result as an ordinary channel.

How to reach it

Press the math button in the toolbar, or g.

The pane's + adds a channel, and opening one shows the graph editor: nodes as boxes, click a box to select it and edit its parameters beside the canvas.

Inside the editor, add node is a menu button whose popover picks the op, so the node arrives as the operation you asked for.

Graph gestures

drag from an output port to an input port to wire them; drag a wired input port off its connection to detach it; click a wire and press Delete to remove it; drag a box to move it. Wheel zooms about the pointer. Drag the background to pan. f fits all nodes into view; Ctrl0 resets the view. tidy, the button beside fit in the editor, lays the graph out in topological columns and frames it. The orange dot marks the output node; click set as output to move it.

Worth knowing

The graph is evaluated as an ordered list, so a node may only read ones above it. A wire drawn right to left re-sorts the list silently so the graph stays valid. A cycle is unrepresentable: the connection is refused rather than created, and the line beneath the form says why — a loop, or a node asked to read itself.

A derived channel is a channel. It appears in the signal panel, can be plotted, measured, exported, and used as a source for another math channel.

The math runs on the stored samples — decimated and averaged — so a cutoff you type in Hz means the rate the filter will actually run at. Change the window across a decimation boundary and the coefficients are rebuilt for the new rate.

A source may only name an acquired channel. The stream's timestamp signal is not one: a graph sourced from it validates and then reads NaN for ever, so the dropdown does not offer it.

The output defaults to the last node, and a node added to a linear graph becomes the output. Choosing an earlier node explicitly is respected.

Every numeric field starts at its own identity value — gain 1, offset 0 — not at the bottom of its range.

Why an operation sometimes does nothing

A graph's output is the node whose value becomes the channel, and it is drawn as the orange dot. A new graph is built source, then operation, and the last node added becomes the output — but a graph whose output is left on the source is valid and simply passes its input through, which is the usual reason a gain or a filter appears to have no effect. Set as output moves the dot.

Apply is insensitive while the graph is incomplete. A line beneath the form says why: an input that is not connected, no output chosen, or a channel node naming a signal the scope is not acquiring. Only the channels being acquired are offered, because a source that is not acquired reads as no data for ever — and a graph that reads NaN is harder to diagnose than one that would not save.

The filters are real filters. A math channel's samples are produced as the stream arrives, once per stored slot, so a low pass carries the history a filter needs. A cutoff typed in hertz is against the stored rate, which is the wire rate until a wide window makes the buffer decimate — the status line's rate is that number, and the filters are rebuilt whenever it changes.

The math channel editor: nodes as boxes on a canvas, the orange dot marking the output, and the selected node's parameters beside it.

A sine source wired through a gain into a filter, with the output on the last node.

Example

[sine] → [gain x2] gives a channel reading y=[-2, 2]. A 100 Hz low pass on the same source passes 50 Hz at 0.97 and 2 kHz at 0.002; a 1 kHz band pass with Q=2 passes 200 Hz at 0.05, 1 kHz at 0.95 and 4 kHz at 0.05. Each derived channel must hold exactly as many samples as the shared clock has time slots.