Fix heat map scaling, add per-channel amplifier

- Add per-channel amplifier (0-100, 1.0x to 10.0x) applied to intensity
  before limiter gates strength
- Fix heat map scaling: use LimitScaleA/B (valA/DesiredA ratio) instead
  of valA/200 — was capping colors at green, never reaching orange
- Scale heat map intensity by limiter ratio so colors reflect actual
  output after limiter
- Remove dead LastIntensityA/B field (replaced by heat map scaling)
- Amp trackbars: 0=1.0x, 100=10.0x, integer value labels
- Close button quits app instead of hiding to tray
This commit is contained in:
2026-08-09 11:55:16 +00:00
parent 4ad85f57ec
commit 4e36580b22
2 changed files with 119 additions and 10 deletions
+82 -4
View File
@@ -31,10 +31,16 @@ public class MainForm : Form
readonly Label _lblRecvB;
readonly TrackBar _limitBarA;
readonly TrackBar _limitBarB;
readonly TrackBar _ampBarA;
readonly TrackBar _ampBarB;
readonly Label _lblLimitA;
readonly Label _lblLimitB;
readonly Label _lblLimitValA;
readonly Label _lblLimitValB;
readonly Label _lblAmpA;
readonly Label _lblAmpB;
readonly Label _lblAmpValA;
readonly Label _lblAmpValB;
readonly CheckBox _chkScaleA;
readonly CheckBox _chkScaleB;
readonly CheckBox _chkSwap;
@@ -61,7 +67,7 @@ public class MainForm : Form
_loopCts = new CancellationTokenSource();
Text = $"Substation {typeof(MainForm).Assembly.GetName().Version}";
ClientSize = new Size(420, 450);
ClientSize = new Size(420, 520);
FormBorderStyle = FormBorderStyle.FixedSingle;
MaximizeBox = false;
StartPosition = FormStartPosition.CenterScreen;
@@ -291,7 +297,60 @@ public class MainForm : Form
_chkScaleB.CheckedChanged += OnLimitChanged;
OnLimitChanged(null, EventArgs.Empty);
Controls.AddRange(new Control[] { _lblBle, _lblWs, _lblDeviceName, _txtDeviceName, _btnConnect, _chkSwap, _btnTest, _btnLive, _btnPattern, _btnStop, _lblAudioDev, _cboAudioDev, _lblTrack, _lblSendA, _heatA, _lblSendB, _heatB, _lblRecvA, _gaugeRecvA, _lblRecvB, _gaugeRecvB, _lblLimitA, _limitBarA, _lblLimitValA, _chkScaleA, _lblLimitB, _limitBarB, _lblLimitValB, _chkScaleB });
_lblAmpA = new Label
{
Text = "Amp A",
Location = new Point(16, 394),
Size = new Size(48, 20),
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
};
_ampBarA = new TrackBar
{
Location = new Point(68, 390),
Size = new Size(212, 45),
Minimum = 0,
Maximum = 100,
TickFrequency = 25,
Value = 0
};
_ampBarA.ValueChanged += OnAmpChanged;
FixTrackbarKeys(_ampBarA);
_lblAmpValA = new Label
{
Text = "0",
Location = new Point(286, 394),
Size = new Size(32, 20),
TextAlign = ContentAlignment.MiddleRight
};
_lblAmpB = new Label
{
Text = "Amp B",
Location = new Point(16, 442),
Size = new Size(48, 20),
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
};
_ampBarB = new TrackBar
{
Location = new Point(68, 438),
Size = new Size(212, 45),
Minimum = 0,
Maximum = 100,
TickFrequency = 25,
Value = 0
};
_ampBarB.ValueChanged += OnAmpChanged;
FixTrackbarKeys(_ampBarB);
_lblAmpValB = new Label
{
Text = "0",
Location = new Point(286, 442),
Size = new Size(32, 20),
TextAlign = ContentAlignment.MiddleRight
};
OnAmpChanged(null, EventArgs.Empty);
Controls.AddRange(new Control[] { _lblBle, _lblWs, _lblDeviceName, _txtDeviceName, _btnConnect, _chkSwap, _btnTest, _btnLive, _btnPattern, _btnStop, _lblAudioDev, _cboAudioDev, _lblTrack, _lblSendA, _heatA, _lblSendB, _heatB, _lblRecvA, _gaugeRecvA, _lblRecvB, _gaugeRecvB, _lblLimitA, _limitBarA, _lblLimitValA, _chkScaleA, _lblLimitB, _limitBarB, _lblLimitValB, _chkScaleB, _lblAmpA, _ampBarA, _lblAmpValA, _lblAmpB, _ampBarB, _lblAmpValB });
// Tray icon — three cached variants: neutral=gray, active=gold, hot=red-orange
_iconNeutral = CreateVoltageIcon(Color.Gray);
@@ -353,8 +412,17 @@ public class MainForm : Form
{
BeginInvoke(() =>
{
_heatA.AddTick(freqA, intA, _state.LastActiveA);
_heatB.AddTick(freqB, intB, _state.LastActiveB);
double aScale = _state.LimitScaleA;
double bScale = _state.LimitScaleB;
var scaledIntA = new byte[4];
var scaledIntB = new byte[4];
for (int i = 0; i < 4; i++)
{
scaledIntA[i] = (byte)Math.Round(intA[i] * aScale);
scaledIntB[i] = (byte)Math.Round(intB[i] * bScale);
}
_heatA.AddTick(freqA, scaledIntA, _state.LastActiveA);
_heatB.AddTick(freqB, scaledIntB, _state.LastActiveB);
});
}
}
@@ -555,6 +623,16 @@ public class MainForm : Form
_lblLimitValB.Text = $"{maxB}";
}
void OnAmpChanged(object? sender, EventArgs e)
{
var ampA = 1.0 + _ampBarA.Value / 100.0 * 9.0;
var ampB = 1.0 + _ampBarB.Value / 100.0 * 9.0;
_state.SetAmpA(ampA);
_state.SetAmpB(ampB);
_lblAmpValA.Text = $"{_ampBarA.Value}";
_lblAmpValB.Text = $"{_ampBarB.Value}";
}
void OnSwapChanged(object? sender, EventArgs e)
{
_state.SwapChannels = _chkSwap.Checked;