feat: 3-bar meters, latching ceiling lamp, and rolling in/out/GR plot

Meters: per-channel |L | GR | R| layout (narrower bars). Ceiling lamp now
latches on a limiter catch and holds, clearing after 3s or on click.

Plot: per-channel selectable scrolling in/out/gain-reduction scope under the
meters, fed by new raw block-peak atomics (separate from the decayed bar
atomics). Histories for all four channels run continuously, so switching tabs
keeps each channel's history. Scroll is time-based with a flow-speed selector
(2/5/15/45 s window) so the window length is accurate regardless of frame rate,
with peak-preserving downsampling between columns.

reset() now zeroes the meters so transport restart shows silence rather than
stale values.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Mikkeli Matlock
2026-06-23 09:53:06 +09:00
parent 9a54413bfa
commit 4c5165b0bc
3 changed files with 282 additions and 33 deletions
+9
View File
@@ -140,6 +140,8 @@ impl Plugin for Codename206 {
comp.reset();
}
self.limiter.reset();
// Transport restart / sample-rate change: drop stale meter values to silence.
self.meters.clear();
}
fn process(
@@ -176,6 +178,7 @@ impl Plugin for Codename206 {
let num_samples = buffer.samples();
let mut lvl_l = [0.0f32; meters::NUM_CHANNELS];
let mut lvl_r = [0.0f32; meters::NUM_CHANNELS];
let mut inp = [0.0f32; meters::NUM_CHANNELS]; // mono input peak (for the scrolling plot)
let mut gr = [0.0f32; meters::NUM_CHANNELS];
let mut lim_gr = 0.0f32;
@@ -214,6 +217,7 @@ impl Plugin for Codename206 {
summed[ch] += band_out[b][ch];
}
if metering {
inp[b] = inp[b].max(band_in[b][0].abs().max(band_in[b][r].abs()));
lvl_l[b] = lvl_l[b].max(band_out[b][0].abs());
lvl_r[b] = lvl_r[b].max(band_out[b][r].abs());
gr[b] = gr[b]
@@ -233,6 +237,7 @@ impl Plugin for Codename206 {
self.limiter.process(&out_frame[..n], &mut lim_frame[..n], ceiling, limiter_release);
if metering {
inp[ALL] = inp[ALL].max(summed[0].abs().max(summed[r].abs()));
lvl_l[ALL] = lvl_l[ALL].max(out_frame[0].abs());
lvl_r[ALL] = lvl_r[ALL].max(out_frame[r].abs());
gr[ALL] = gr[ALL]
@@ -254,6 +259,10 @@ impl Plugin for Codename206 {
meters::decay_store(&self.meters.level_l[i], lvl_l[i], w);
meters::decay_store(&self.meters.level_r[i], lvl_r[i], w);
meters::decay_store(&self.meters.gain_reduction_db[i], gr[i], w);
// Raw block peaks for the scrolling plot (editor keeps its own history).
meters::store_instant(&self.meters.plot_in[i], inp[i]);
meters::store_instant(&self.meters.plot_out[i], lvl_l[i].max(lvl_r[i]));
meters::store_instant(&self.meters.plot_gr[i], gr[i]);
}
meters::decay_store(&self.meters.limiter_gr_db, lim_gr, w);
}