fix: math in a file view -- the buffer was emptied, and the derived ring filled twice

Two defects, both reached by adding a math channel to an open waveform or a replayed
event, and both measured before and after.

**A file view has no producer, so a structural change left it empty.** `set_math_channels()`
rebuilds the channels *and* the buffer, and a rebuild drops the history: right for a stream,
whose producer refills it from the next packet, and wrong for a file, which has nothing to
refill it with. The `--open` dump read `0 samples vs 0 time slots` for *every* channel,
the file's own `sine`/`square`/`ramp`/`noise` included, though the load had reported 402 --
that is what "adding a math node breaks the plotter" was. `reload_file_view()` re-reads the
file after such a change, which is also what computes the derived channels over it: the
load's own pushes run the math once the set is in place, so `--open` with a session that
defines graphs works for the first time.

**The file path pushed into the derived rings, and so did the engine.** `push_loaded_slot()`
did not honour the rule `ChannelInfo::math` states for the packet path ("the ingest must skip
it"), so each loaded slot put a value in a derived ring and `push_math_sample()` then put the
computed one: two samples per slot, a trace at double rate -- the derived channels read
`804 samples vs 402 time slots`. Skipping them there is the whole fix.

Readings now, all equal, which is the assertion this file's own invariant makes:

    --open the file:  math x2  402 samples vs 402 time slots, y=[-1.9021, 0.0063]  (2x the sine)
                      math lp  402 vs 402, mean=-0.4900 (a real filter output, not zero)
    live:             math x2  25100 vs 25100
    replayed event:   math x2  4000 vs 4000

I first tried filtering the file's *derived columns* out by name, since an export writes
every plotted channel. It removed the double count and zeroed `math lp`, because the column
it dropped was the source a session graph reads -- so it is reverted: those columns are
legitimate data, and the fix belongs in the push, not the loader.
This commit is contained in:
Martino Ferrari committed 2026-10-12 19:49:39 +02:00
1 parent c3d588f03d
commit b090cc2a21
5 files changed
+52

No files matched your search

+4
View File
@@ -18,6 +18,10 @@ void apply_math_channels(App& app) {
// `set_math_channels()` takes the model's lock itself -- holding it here is a self-deadlock on a
// non-recursive mutex, and it is exactly how the first version of the probe hung the app.
app.model->set_math_channels(app.math);
// The structural rebuild above replaced the buffer and dropped its history. A stream's producer
// refills that; a file's nothing does, so the view is re-read -- and with the math set now in place
// the reload computes the derived channels over the file as it goes.
reload_file_view(app);
rebuild_math_pane(app);
schedule_layout_save(app);
}