fix(dock): the master ladder moves when no session is running

Reported: no activity in the master meter.

Cause: `MasterLevel` measures the buffer the ENCODER receives, and that buffer only exists while the
mix is being pulled — streaming or recording. Idle, nothing fills it, so the master read zero while
the bays below it moved. A master that is dead between sessions is a gap in the design.

Now: while a session runs the master shows the measured mix (unchanged); idle it shows an estimate
computed from the same measured sources and the same gains the mix applies
(`MeterScale.MonitorFraction`, pure + tested). Two ladders can therefore never tell contradictory
stories about whether audio exists.

Guard: MeterScaleTests pins the estimate — silence reads zero, a quiet source at unity is visible,
two sources add, and gain is applied in the LINEAR domain like the mix (scaling the display fraction
would be a different, wrong curve).
This commit is contained in:
2026-10-30 14:01:29 -07:00
parent ec293e54b0
commit e92ce4bb63
3 changed files with 30 additions and 2 deletions
+8 -2
View File
@@ -262,8 +262,14 @@ public partial class MainViewModel
}
}
/// <summary>Master ladder input: the measured mix, 0…1 on the same display scale.</summary>
public double MasterMeterFraction => AudioLevelMeter.ToDisplay(_audioMixer.MasterLevel);
/// <summary>Master ladder input: the MEASURED mix while a session runs (that is the buffer the
/// encoder receives), and an estimate from the measured sources when idle — otherwise the master
/// sits at zero between sessions while every bay below it moves.</summary>
public double MasterMeterFraction =>
IsLive || IsRecording
? AudioLevelMeter.ToDisplay(_audioMixer.MasterLevel)
: Helpers.MeterScale.MonitorFraction((float)AudioLevel, MicVolume,
(float)GameAudioLevel, GameAudioVolume);
public string MasterLevelLabel => Helpers.GainDb.Label(Helpers.GainDb.ToDb(_audioMixer.MasterLevel)) + " dB";