Let AGC raise the noise floor further to bring up a distant voice

AGC2 won't amplify the background noise above -50 dBFS, which also caps
the gain for a voice barely above that noise: a distant talker ended up
5 dB quieter than a near one with noise suppression on, 12 dB with it
off. A "Boost quiet speech" setting (0-20 dB, default 0) raises the cap,
live, on desktop and Android.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 22:08:50 +00:00
parent 491cbcb259
commit 73a15a8cfc
10 changed files with 87 additions and 2 deletions

View File

@@ -33,6 +33,7 @@ final class DevicesPanel extends FormPanel {
private final JSlider denoiseLevel;
private final JCheckBox typingCheck;
private final JCheckBox agcCheck;
private final JSlider agcBoost;
private final JCheckBox mutedWarningCheck;
DevicesPanel(Settings settings, AudioIo io, VoiceOutput livePlayback,
@@ -99,6 +100,12 @@ final class DevicesPanel extends FormPanel {
agcCheck.setToolTipText("<html><b>Automatic gain control</b> normalises your "
+ "microphone loudness to a target level, boosting quiet mics and taming "
+ "loud ones.</html>");
agcBoost = new JSlider(0, Settings.MAX_AGC_BOOST_DB, settings.agcBoostDb);
agcBoost.setMajorTickSpacing(5);
agcBoost.setPaintTicks(true);
limitWidth(agcBoost, SLIDER_WIDTH);
agcBoost.setToolTipText("<html>Lets AGC bring up a quiet or distant voice further, "
+ "at the cost of up to this many dB more background noise (0&ndash;20 dB).</html>");
c.gridx = 0;
c.gridy = row++;
@@ -113,9 +120,11 @@ final class DevicesPanel extends FormPanel {
c.gridy = row++;
add(agcCheck, c);
c.gridwidth = 1;
addRow(this, c, row++, new JLabel("Boost quiet speech:"), agcBoost);
Runnable syncNoise = () -> {
denoiseLevel.setEnabled(denoiseCheck.isSelected());
agcBoost.setEnabled(agcCheck.isSelected());
applyLive.accept(m -> {
m.setNoiseSuppression(denoiseCheck.isSelected());
m.setDenoiserLevel(denoiseLevel.getValue());
@@ -128,6 +137,8 @@ final class DevicesPanel extends FormPanel {
agcCheck.addActionListener(e -> syncNoise.run());
denoiseLevel.addChangeListener(e ->
applyLive.accept(m -> m.setDenoiserLevel(denoiseLevel.getValue())));
agcBoost.addChangeListener(e ->
applyLive.accept(m -> m.setAgcBoost(agcBoost.getValue())));
syncNoise.run();
mutedWarningCheck = new JCheckBox("Beep when talking while muted", settings.mutedTalkWarning);
@@ -156,6 +167,7 @@ final class DevicesPanel extends FormPanel {
target.denoiserLevel = denoiseLevel.getValue();
target.typingAttenuation = typingCheck.isSelected();
target.agc = agcCheck.isSelected();
target.agcBoostDb = agcBoost.getValue();
target.mutedTalkWarning = mutedWarningCheck.isSelected();
}