Skip to content

fix(ui): keep noise-floor readouts single-axis after VAD shift#132

Merged
flexiondotorg merged 3 commits into
mainfrom
vad-align
Jun 17, 2026
Merged

fix(ui): keep noise-floor readouts single-axis after VAD shift#132
flexiondotorg merged 3 commits into
mainfrom
vad-align

Conversation

@flexiondotorg

Copy link
Copy Markdown
Contributor

The VAD redesign moved Noise.Floor / MeasuredNoiseFloor onto the K-weighted
momentary-LUFS axis, but the TUI and report still mixed that with the
astats RMS dBFS room-tone floor. Same-named "noise floor" numbers disagreed
across surfaces and one resolver silently switched axes. This branch pins
every displayed floor to the astats RMS dBFS axis and documents the trap.

  • Done-box "Noise floor" now shows a matched input->output room-tone pair,
    both on the astats RMS dBFS axis and the same measurement method, so the
    before/after is honestly comparable (was a single value that swapped stages)
  • Live Analysis box and done-box "before" both read one resolver
    (InputRoomToneFloorDB) so they cannot diverge
  • Remove the wrong-axis fallback to NoiseProfile.MeasuredNoiseFloor
    (momentary-LUFS): an absent ElectedRoomToneSample now yields ok=false,
    not a cross-axis number; guard NaN/Inf/zero RMSLevel as unmeasured
  • Report definitions clarify floor_dbfs (input VAD momentary-LUFS seed) vs
    measured_floor_dbfs (input astats RMS) as distinct quantities
  • Document the two axes and the no-cross-axis rule in AGENTS.md
    ("Measurement axes") to stop the class of bug recurring

Display-only: byte-identical audio and run-record data, report text only.

…/after pair

  Display-only change: the done-box "Noise floor" now shows a matched
  input→output room-tone pair on the astats RMS dBFS axis (both on the same
  measurement method and axis for honest comparison), replacing a confusing
  single value that silently swapped between input and output stages. Report
  definitions clarify floor_dbfs (input VAD momentary-LUFS seed) vs
  measured_floor_dbfs (input RMS) as distinct quantities. Byte-identical
  audio and run-record data; report text only.

Signed-off-by: Martin Wimpress <code@wimpress.io>
  `InputRoomToneFloorDB` is the single display resolver for input room-tone RMS
  floor, shared by the done-box "before" and live Analysis box. Its fallback to
  `NoiseProfile.MeasuredNoiseFloor` silently switches axes: that field is
  K-weighted momentary-LUFS (the VAD/afftdn-seed floor, overwritten in
  detectVoiceActivity), not astats RMS dBFS. An absent ElectedRoomToneSample
  must yield ok=false, not a cross-axis number.

  - Remove the momentary-LUFS fallback entirely; return ok=false when no
    ElectedRoomToneSample exists
  - Add guards for NaN/Inf/zero RMSLevel (unmeasured) - return ok=false
  - Fix stale comment claiming both operands are astats RMS (fallback was LUFS)
  - Reference the new "Measurement axes" section in AGENTS.md
  - Centralise the resolver so live box and done box cannot diverge
  - Update tests: no momentary-LUFS leakage, live==done invariant on both paths

  Fixes the latent defect caught during the VAD axis audit.

Signed-off-by: Martin Wimpress <code@wimpress.io>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 15 files

Confidence score: 4/5

  • In internal/ui/summary.go, the discarded boolean from InputRoomToneFloorDB means missing/zero/NaN room-tone values render as "0 dB" in the Analysis box instead of an unmeasured state, which can mislead users into thinking a valid measurement exists and create inconsistency with the done-box display—propagate that bool and show n/a (or equivalent guard) before merging.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread internal/ui/summary.go Outdated
  The live Analysis box was discarding the ok bool from InputRoomToneFloorDB,
  rendering unmeasured room-tone floors as "0 dB" and computing a bogus
  SeparationDB against that zero. The done-box correctly shows "n/a" when
  unmeasured, so the two surfaces diverged on the exact axis-consistency this
  branch guarantees.

  - Add HasNoiseFloor bool field to AdaptedSummary (matches HasSpeech/HasSibilance
    convention)
  - Capture InputRoomToneFloorDB's ok bool; compute SeparationDB only when both
    a SpeechProfile and a measured floor exist
  - Render unmeasured floor as dim "n/a" and suppress SNR Gap row, matching
    doneBoxNoiseFloorRow convention exactly
  - Extend live-box == done-box invariant test to lock the unmeasured path;
    add TestUnmeasuredFloorNoSeparation

Signed-off-by: Martin Wimpress <code@wimpress.io>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 4 files (changes from recent commits).

Auto-approved: UI display fixes to keep noise-floor readouts on the astats RMS axis; adds input/output floor resolvers and updates done-box and live analysis. Display-only, no audio changes.

Re-trigger cubic

@flexiondotorg flexiondotorg merged commit 94e4432 into main Jun 17, 2026
16 checks passed
@flexiondotorg flexiondotorg deleted the vad-align branch June 17, 2026 18:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant